记一次MariaDB主从复制的搭建

环境:
  • 系统: CentOS release 6.3
  • 内核: 2.6.32-431.23.3.el6.centos.plus.x86_64
  • 数据库版本:
    • master: 10.1.16-MariaDB MariaDB Server
    • slave: 10.1.34-MariaDB MariaDB Server
问题描述:
  • 使用mysqldump备份工具在master上面进行全备,然后根据备份获取得到的binlog file和position搭建主从环境,但是在start slave之后报错,出现1062错误。
  • mysqldump备份命令:

     mysqldump -S/var/lib/mysql/mysql.sock  -uroot -p --single-transaction --master-data=2 zst > 20180719_zst.sql
  • 刚刚开始的时候以为是极少部分数据或者说因为slave上面有进行write导致出现1062主键冲突的错误,然后直接在slave上面根据报错的主键进行删除行,然后再进行start slave,但是发现发现这样的数据有很多,然后直接查询导致这样的原因。
猜想:
  • 因为线上的数据是innodb和tokudb引擎混合使用,所以我怀疑是tokudb引擎不支持快照备份,但是mysqldump只有支持MVCC的数据库引擎才支持快照备份,tokudb引擎是支持MVCC和事务的。最后我询问了一下其他人员得到tokudb引擎不支持mysqldump的一致性快照备份。所以我打算自己实验一下。
实验:
  1. 实验环境:

    • master: 172.16.3.5
    • slave: 172.16.3.7
    • sysbench_host: 172.16.3.15
  2. 安装MariaDB(master和slave都需安装)

    shell> wget https://downloads.mariadb.com/MariaDB/mariadb-10.1.34/yum/rhel/mariadb-10.1.34-rhel-6-x86_64-rpms.tar
    shell> tar -xf mariadb-10.1.34-rhel-6-x86_64-rpms.tar
    shell> cat sys/kernel/mm/transparent_hugepage/enabled ##需要关闭大页传输
    always madvise [never] ## 是never是正确的
    shell> echo never > /sys/kernel/mm/transparent_hugepage/enabled
    shell> echo never > /sys/kernel/mm/transparent_hugepage/defrag
    shell> cd mariadb-10.1.34-rhel-6-x86_64-rpms
    shell> ./setup_repository
    shell> yum install Mariadb-Server
  3. 查看是否支持TokuDB

    ......
    *************************** 5. row ***************************
      Engine: TokuDB
     Support: DEFAULT
     Comment: Percona TokuDB Storage Engine with Fractal Tree(tm) Technology
    Transactions: YES
          XA: YES
    Savepoints: YES
    *************************** 6. row ***************************
    ......
  4. 搭建主从

    mysql> change master to
    -> master_host='172.16.3.5',
    -> master_user='rpl',
    -> master_password='new_password',
    -> master_port=3306,
    -> master_log_file='mysql-bin.000010',
    -> master_log_pos=258482739;
  5. sysbench压测(sysbench_host上面运行)

    • 验证思路: 因为我的目的是为了验证tokudb不支持快照备份,所以我首先我只需要不停往数据库里面写数据,并且保证我在备份的期间还有数据写入。所以尽可能的将table size的值弄大些,这样子的话那么写数据的时间比较长,在写入数据的时候在master上面进行mysqldump的一致性快照备份,将获取得到的数据导入slave中,并且根据备份文件中的binlog file和position搭建主从,假如在start slave的时候没有出现1062主键冲突的情况,那么说明tokudb是支持一致性快照备份的,假如出现了1062错误(不是说只有一条,而是多条,具体的验证可以设置sql_slave_skip_counter设置空事务,可以看到需要跳过很多的空事务;或者说上诉说的删除slave上面主键冲突的row,start slave。因为是为了实验所以没有开启GTID。)
    sysbench oltp_insert.lua --threads=10 --report-interval=5 --db-driver=mysql --mysql-host=172.16.3.5 --mysql-port=3306 --mysql-user=root --mysql-password='new_password' --mysql-db=zst --mysql_storage_engine=tokudb --tables=10 --table_size=2000000 prepare
  6. 实验结果

    ......
    ......
    Last_SQL_Errno: 1062
               Last_SQL_Error: Could not
    execute Write_rows event on table zst.sbtest1; Duplicate entry '8' for key
    'PRIMARY', Error_code: 1062; handler error HA_ERR_FOUND_DUPP_KEY; the event's
    master log mysql-bin.000005, end_log_pos 2678
    ......
    ......
总结
  • 可以很明确的清楚tokudb引擎不支持事务的一致性快照。
  • tokudb的备份工具

    • 使用 Percona 版本的 mysqldump 可以备份 tokuDB 的数据,并且额外提供了一个参数 lock-for-backup 来保证数据一致性。(https://www.percona.com/doc/percona-server/LATEST/management/backup_locks.html#mysqldump)
    mysqldump has also been extended with a new option, lock-for-backup (disabled by default). When used together with the --single-transaction option, the option makes mysqldump issue LOCK TABLES FOR BACKUP before starting the dump operation to prevent unsafe statements that would normally result in an inconsistent backup.
    When used without the single-transaction option, lock-for-backup is automatically converted to lock-all-tables.
    Option lock-for-backup is mutually exclusive with lock-all-tables, i.e. specifying both on the command line will lead to an error.
    If the backup locks feature is not supported by the target server, but lock-for-backup is specified on the command line, mysqldump aborts with an error.
    • 物理备份工具,也是编译过的xtrabackup
    https://github.com/XeLabs/tokudb-xtrabackup
    • 在使用tokudb备份的时候建议最好使用物理备份,因为在tokudb是一个压缩引擎,线上使用innodb和tokudb混合引擎物理磁盘使用了33G,但是使用mysqldump备份出来有88G的数据,所以说一个磁盘和一个效率问题并不推荐使用逻辑备份tokudb,尽量还是使用物理备份。
问题解决
  • 虽然是验证了tokudb不支持mysqldump的一致性快照备份,但是实际问题还是没有解决。
  • 最后还是设置slave_skip_errors的值为1062然后重启slave,一段时间等之后(等主键冲突的数据全部同步过去)在关掉这个参数,然后再重启slave。最后实验percona的工具集pt-table-cheksum和pt-table-sync进行校验同步。