容器与centos7

容器默认不启动init进程的,导致centos7中执行systemctl时会出现如下错误:

其实,systemctl完全可以通过参考配置文件,启动命令就行,当试图去写一个脚本替换掉systemctl时,发现已经有人做了:https://github.com/gdraheim/docker-systemctl-replacement

把这里的systemctl.py 替换掉systemctl命令即可。

另外,虽然我们可以直接使用systemctl了,但是,某些工具未必能,如: ansible service模块,timedatectl。

ansible service模块还会参考是否存在目录 /run/systemd/system 。 可以手动创建该目录将其欺骗。

 

 

centos7容器修改时区:

/usr/share/zoneinfo/Asia/Shanghai 和 /etc/localtime 并不属于相同的rpm包,前者属于: tzdata   后者属于: systemd

关于表修复、表重构

  1. 表修复是用于解决一致性问题
  2. 表重构是用于解决碎片问题
  3. runstats可以用于所有表或单个表
  4. 也可以通过reorgchk on table all来检查是否需要重构

 

Operation not allowed for reason code reason-code on table table-name.
Explanation: Access to table table-name is restricted. The cause is based on the following reason codes reason-code: 7
The table is in the reorg pending state. This can occur after an ALTER TABLE statement containing a REORG-recommended operation.7
Reorganize the table using the REORG TABLE command (note that INPLACE REORG TABLE is not allowed for a table that is in the reorg pending state).
其中:
reorg table <tablename> 通过重构行来消除“碎片”数据并压缩信息,对表进行重组。
runstats on table <tbschema>.<tbname> 收集表 <tbname> 的统计信息。
reorgchk on table all 确定是否需要对表进行重组,对于对所有表自动执行 runstats 很有用。
>>> reorg 和runstats 都是单个表优化,初始化的命令:
runstats on table administrator.test;
reorg table administrator.test;

openldap 占用大量内存问题

我使用openldap仅仅是几十条数据用于测试,但是,docker版本的openldap却启动后就占用 725MB的内存,显然不太合理,尤其是跑在我的笔记本上的,更不能如此的浪费,查了一下,相关讨论: https://github.com/nickstenning/docker-slapd/issues/8

解决办法:

原值是: 1048576。 然后,重启slapd,内存使用为5MB,一下子省去了700+MB的内存,简直太好了,当然,我是虚拟机中使用的,要重启虚拟机才能释放给系统使用。

Ansible 基础

  1. 指定hosts文件
    1. 默认 /etc/ansible/hosts
    2. 可以通过-i选项指定
  2. 关于facts
    1. 每台目标机器上可以配置一些属性,就是所谓的facts,配置目录:/etc/ansible/facts.d/
  3. 缓存facts:
    1. 参考:
      1. https://www.imooc.com/article/48607
      2. https://www.jianshu.com/p/0cd54330e8b8
    2. 可以缓存到文件或缓存到redis
      1. 设置为参考缓存
        gathering 值设置为smart
        smart 表示默认收集 facts,但 facts 已有的情况下不会收集,即使用缓存 facts;
        implicit 表示默认收集 facts,要禁止收集,必须使用 gather_facts: False
        explicit 则表示默认不收集,要显式收集,必须使用 gather_facts: Ture
      2. 缓存到json文件:

        需要手动创建目录,只要文件存在就不会再次获取,哪怕设置为不参考缓存,只要设置了缓存,也会写缓存的
      3. 缓存到redis:

         
      4. 刷新缓存
        1. 对于文件缓存,可直接删除缓存文件
        2. 也可以直接  ansible -m setup, 这个会无视缓存文件而重新获取facts的
    3. 设置持久连接
      1. ssh中只设置: -o ControlPath=/home/phpor/.ansible/cp/4206c512dc  而不设置 -o ControlPersist=3600s 是不能持久连接的
    4. 设置并发
      1. 1个playbook中可以设置多个任务,在多台机器上执行,可以通过serial: 1 让所有机器顺序执行
      2. 并行执行的情况下,是按照playbook中定义的任务一个任务一个任务的执行的,第一个任务在serial定义的数量的机器上执行以后,在执行下一个任务,如果serial没有定义,则现在所有的机器上执行完第一个任务,再在所有的机器上执行下一个任务;如果需要每个机器执行完所有任务后再在下一个机器上执行,则设置serial: 1 (注意: 不是 并发为1就行的,即使并发为1,如果没有serial设置的话,也是所有机器上执行完第一个任务再在所有机器上开启下一个任务,对于升级应用的时候非常有用,因为步骤通常是:摘掉负载均衡,升级,挂回到负载均衡; 如果一下子都摘掉就完蛋了)
      3. -f 选项可以指定同时在多少个机器上执行
      4. 通过 async 和poll可以同时在所有机器上执行

        你会发现当你使用上面的例子控制超过5台机器的时候,command.在上面yum模块会先在5台机器上跑,完成后再继续下面的机器.而上面command模块的任务会一次性在所有机器上都执行了,然后监听它的回调结果
    5. 限制并发: https://www.cnblogs.com/breezey/p/10996651.html
    6. playbook中的hosts可以定义在哪些机器上执行,可以通过–limit选项只在指定的机器上执行,不过limit指定的主机一定要是playbook中的hosts指定的主机的子集,不能是playbook中的hosts指定的主机的集合外的机器
    7. include_tasks: 包含子任务
      1. 参考: https://www.cnblogs.com/jinyuanliu/p/10655374.html
      2. 子任务的文件格式和playbook的格式不太一样,不能包含hosts属性,而playbook必须包含hosts属性
      3. 包含的任务地点文件名不能使用通配符
    8. 关于变量加载的约定:
      1. hosts文件旁边的 group_vars 和 host_vars 目录中的 .yml  .yaml .json 扩展名或无扩展名的文件会被参考加载到对应的group和host的变量,执行playbook时,如果playbook dir(默认当前目录,可以通过–playbook-dir指定)中也存在 group_vars 或 host_vars 目录,则该目录的优先级更高,参考:https://docs.ansible.com/ansible/latest/user_guide/intro_inventory.html#group-variables
      2. roles中的task中引用的文件默认是files,templates,tasks 子目录中的文件: 参考: https://docs.ansible.com/ansible/latest/user_guide/playbooks_reuse_roles.html
        如果tasks目录中和template目录中有相同文件名的文件,则引用的时候可能会搞错,所以,尽量不重名吧
    9. 变量引用:
      1. 关联数组中的变量可以用 arr[‘key’]  或 arr.key 两种不同的方式引用

db2look 基本使用

  1. db2look导出的文件的字符集受两个配置的影响
    1. LANG
      1. 影响文件的表头
      2. 建议设置LANG=C,使得文件的头部和编码无关,不至于影响某些编辑器(如vim)对文件编码的检测
    2. DB2CODEPAGE
      1. 影响文件的内容
      2. 通过db2set进行设置,该设置是全局的,参考: https://phpor.net/blog/post/12804
  2. db2look 默认不导出创建数据库的语句,也不导出表存在就删除的drop语句,可以通过选项开启:
    1. -createdb: 生成创建数据库的语句
    2. -dp: Generate DROP statement before CREATE statement
    3. -printdbcfg: Generate UPDATE DB CFG commands for the database configuration parameters
      1. 如果目标数据库和源数据库配置期望一样的话,这样会比较方便

DB2 创建实例

首先,在安装目录find db2icrt;

db2icrt 需要指定db2fenc账号和实例账号,而且,这些账号不会自动创建,需要事先创建:

创建实例: (命令是在/opt/ibm/db2/V11.1/instance 下面的,默认没有在path目录中)

db2 create 的数据库默认在db2实例账户的家目录下的。

启动实例:

db2 实例名也不能多于8个字符(直到db2 11 中依然如此),哎

创建实例的时候,会自动往 /etc/services 中注册一个条目, 如: (不知道这个是如何选择到50001端口的,这是是因为另一个实例已经占用了 50000端口)

db2c_db2ist11 50001/tcp

 

创建实例时并不立即生成实例相关目录,只是在实例用户的目录中生成了sqllib目录,甚至在db2start后,都并不产生数据库的目录的。

 

DB2 和 Docker 的恩怨

DB2 11.5 的容器镜像,启动的时候,自动创建了数据库TESTDB, 但是没有自动启动DB2 manager,进入db2inst1账号后,由于db2admin没有在PATH里面,db2start会失败,所以,将路径 /opt/ibm/db2/V11.5/das/bin 假如到PATH 后,db2start可以正常启动,但是,db2 connect  to testdb 时,就会报错,然后db2 manager进程就退出了。

然而,也找不到哪里有有用的错误日志。

db2 manager启动的时候,数据库本身并没有启动,可以激活数据库,也可以第一次connect to 数据库的时候自动激活,目前的情况就是第一次连接的时候失败,应该就是因为数据库启动失败

先怀疑一下:

  1. 可能是日志文件配置的太多、太大,磁盘不够,所以数据库启动不了
  2. 可能是启动数据库需要的内存不能满足需求,所以数据库启动失败

检查:

db2 get db cfg for testdb

日志文件存储需求: 1024 * 4K * (13+12) = 100MB ;

这个完全没有问题。

内存需求: 1237664 * 4K =  4.8GB  ,然而,我的容器限制的是2GB的内存

修改内存需求配置:

修改后: 4096*4KB= 16MB  (这个是非常小的,这里仅仅是快速测试一下是不是内存问题导致的失败,所以,随便写了一个很小的值)

再次测试,发现连接数据库正常了

 

总结:

  1. 注意修改数据库相关配置

问题:

  1. 默认的数据库内存大小是如何确定的?

DB2之动态sql

DB2中记录了sql的执行次数和平均时长,执行总时长以及CPU时间。

但是,这些数据是多长时间内的呢?

  1. 这些数据仅仅是记录在内存中的,重启数据库就没有了,也就是说,数据是从启动数据库开始的
  2. 鉴于内存大小的限制,动态sql也不可能保存启动数据库以来所有的sql的统计信息,那么是保存最近多长时间或多少条sql的记录吗?
    1. 应该都不是,仅仅和分配的内存大小有关系,查看分配的内存大小:

      默认是4K的内存
    2. 如果空间用完后,新的sql进来的话,会如何处理呢?
      1. 如果新的sql已经存在在内存中,则仅仅修改已有记录的执行次数、执行时间等值就行了,不需要新的空间
      2. 如果是一个全新的sql,则直接丢弃?
    3. 如何查看动态sql内存的使用情况?
      1. 通常情况下,数据库中的sql类型是非常有限的,都记录下来是可能的
  3. 动态sql的信息
    1. 动态sql记录的是执行次数、平均执行时间,并不记录某次的慢查询,如果偶尔又一次10s的查询,但是有1000次的查询都在1ms以内,那么,平均查询时间在10ms以内,这样的话,10s的那次慢查询是被淹没了的,如何发现10s的那次慢查询呢?