当前位置:Gxlcms > 数据库问题 > [mysql]一次主从数据不一致的问题解决过程

[mysql]一次主从数据不一致的问题解决过程

时间:2021-07-01 10:21:17 帮助过:30人阅读

# yum install perl-DBI perl-DBD-MySQL perl-TermReadKey perl-Time-HiRes #安装工具 # wget percona.com/get/percona-toolkit.tar.gz # tar zxvf percona-toolkit-2.2.14.tar.gz # cd percona-toolkit-2.2.14 # perl Makefile.PL && make && make install

校验数据一致性

建立用户并授权

注意这里要在主从创建一个同名的用户,可以从主库访问从库,主库本地可以访问主库。工具的使用都是在主库的服务器上进行,使用
pt-table-checksum校验数据一致性。

从库mysql操作

  1. <code class=" hljs sql"><span class="hljs-operator"><span class="hljs-keyword">GRANT</span> <span class="hljs-keyword">SELECT</span>,PROCESS, SUPER, REPLICATION SLAVE <span class="hljs-keyword">ON</span> *.* <span class="hljs-keyword">TO</span> <span class="hljs-string">‘checksums‘</span>@<span class="hljs-string">‘192.168.1.100‘</span> IDENTIFIED <span class="hljs-keyword">BY</span> <span class="hljs-string">‘slavecheck‘</span>;</span>
  2. flush privileges;</code>

?
主库mysql操作

  1. <code class=" hljs sql"><span class="hljs-operator"><span class="hljs-keyword">GRANT</span> <span class="hljs-keyword">SELECT</span>, PROCESS, SUPER, REPLICATION SLAVE <span class="hljs-keyword">ON</span> *.* <span class="hljs-keyword">TO</span> <span class="hljs-string">‘checksums‘</span>@<span class="hljs-string">‘192.168.1.100‘</span> IDENTIFIED <span class="hljs-keyword">BY</span> <span class="hljs-string">‘slavecheck‘</span>;</span>
  2. <span class="hljs-operator"><span class="hljs-keyword">GRANT</span> <span class="hljs-keyword">SELECT</span>,<span class="hljs-keyword">INSERT</span>,<span class="hljs-keyword">UPDATE</span>,<span class="hljs-keyword">DELETE</span> <span class="hljs-keyword">ON</span> radius.checksums <span class="hljs-keyword">TO</span> <span class="hljs-string">‘checksums‘</span>@<span class="hljs-string">‘192.168.1.100‘</span>;</span>
  3. flush privileges;</code>

校验时候需要在主mysql 中新建一张表,新建用户需要有读写的权限,这里是把校验表建立在radius库中。

pt-table-checksum 校验

校验是在主库服务器上进行的

  1. <code class=" hljs lasso">主库shell中执行
  2. pt<span class="hljs-attribute">-table</span><span class="hljs-attribute">-checksum</span> h<span class="hljs-subst">=</span><span class="hljs-string">‘192.168.1.100‘</span>,u<span class="hljs-subst">=</span><span class="hljs-string">‘checksums‘</span>,p<span class="hljs-subst">=</span><span class="hljs-string">‘slavecheck‘</span>,P<span class="hljs-subst">=</span><span class="hljs-number">3306</span> <span class="hljs-attribute">-d</span> radius <span class="hljs-subst">--</span>nocheck<span class="hljs-attribute">-replication</span><span class="hljs-attribute">-filters</span> <span class="hljs-subst">--</span>replicate<span class="hljs-subst">=</span>radius<span class="hljs-built_in">.</span>checksums
  3. <span class="hljs-subst">--</span>nocheck<span class="hljs-attribute">-replication</span><span class="hljs-attribute">-filters</span> :不检查复制过滤器,建议启用。后面可以用<span class="hljs-subst">--</span>databases来指定需要检查的数据库。
  4. <span class="hljs-subst">--</span>no<span class="hljs-attribute">-check</span><span class="hljs-attribute">-binlog</span><span class="hljs-attribute">-format</span> : 不检查复制的binlog模式,要是binlog模式是ROW,则会报错。
  5. <span class="hljs-subst">--</span>replicate<span class="hljs-attribute">-check</span><span class="hljs-attribute">-only</span> :只显示不同步的信息。
  6. <span class="hljs-subst">--</span>replicate<span class="hljs-subst">=</span> :把checksum的信息写入到指定表中,建议直接写到被检查的数据库当中。
  7. <span class="hljs-subst">--</span>databases<span class="hljs-subst">=</span> :指定需要被检查的数据库,多个则用逗号隔开。
  8. <span class="hljs-subst">--</span>tables<span class="hljs-subst">=</span> :指定需要被检查的表,多个用逗号隔开
  9. h<span class="hljs-subst">=</span><span class="hljs-number">192.168</span><span class="hljs-number">.1</span><span class="hljs-number">.100</span> :Master的地址
  10. u<span class="hljs-subst">=</span>checksums :用户名
  11. p<span class="hljs-subst">=</span>slavecheck :密码
  12. P<span class="hljs-subst">=</span><span class="hljs-number">3306</span> :端口</code>

这个脚本在主库机器上运行,会自动找到从库地址,并用相同的用户登录,然后对比。

–replicate 选项是建立一个表来存储对比信息,这个表一定要能同步到从库中,如果checksums用户没有建表权限,请自行建立好表

建表语句

  1. <code class=" hljs sql"><span class="hljs-operator"><span class="hljs-keyword">CREATE</span> <span class="hljs-keyword">TABLE</span> <span class="hljs-keyword">IF</span> <span class="hljs-keyword">NOT</span> <span class="hljs-keyword">EXISTS</span> <span class="hljs-string">`radius`</span>.<span class="hljs-string">`checksums`</span> (
  2. db <span class="hljs-keyword">CHAR</span>(<span class="hljs-number">64</span>) <span class="hljs-keyword">NOT</span> <span class="hljs-keyword">NULL</span>,
  3. tbl <span class="hljs-keyword">CHAR</span>(<span class="hljs-number">64</span>) <span class="hljs-keyword">NOT</span> <span class="hljs-keyword">NULL</span>,
  4. chunk <span class="hljs-keyword">INT</span> <span class="hljs-keyword">NOT</span> <span class="hljs-keyword">NULL</span>,
  5. chunk_time <span class="hljs-keyword">FLOAT</span> <span class="hljs-keyword">NULL</span>,
  6. chunk_index <span class="hljs-keyword">VARCHAR</span>(<span class="hljs-number">200</span>) <span class="hljs-keyword">NULL</span>,
  7. lower_boundary TEXT <span class="hljs-keyword">NULL</span>,
  8. upper_boundary TEXT <span class="hljs-keyword">NULL</span>,
  9. this_crc <span class="hljs-keyword">CHAR</span>(<span class="hljs-number">40</span>) <span class="hljs-keyword">NOT</span> <span class="hljs-keyword">NULL</span>,
  10. this_cnt <span class="hljs-keyword">INT</span> <span class="hljs-keyword">NOT</span> <span class="hljs-keyword">NULL</span>,
  11. master_crc <span class="hljs-keyword">CHAR</span>(<span class="hljs-number">40</span>) <span class="hljs-keyword">NULL</span>,
  12. master_cnt <span class="hljs-keyword">INT</span> <span class="hljs-keyword">NULL</span>,
  13. ts <span class="hljs-keyword">TIMESTAMP</span> <span class="hljs-keyword">NOT</span> <span class="hljs-keyword">NULL</span> <span class="hljs-keyword">DEFAULT</span> <span class="hljs-keyword">CURRENT_TIMESTAMP</span> <span class="hljs-keyword">ON</span> <span class="hljs-keyword">UPDATE</span> <span class="hljs-keyword">CURRENT_TIMESTAMP</span>,
  14. <span class="hljs-keyword">PRIMARY</span> <span class="hljs-keyword">KEY</span> (db, tbl, chunk),
  15. INDEX ts_db_tbl (ts, db, tbl)
  16. ) ENGINE=INNODB;</span></code>

我这里手动建立好表之后出现了如下的错误

  1. <code class=" hljs coffeescript"><span class="hljs-number">6</span>-<span class="hljs-number">16</span><span class="hljs-attribute">T16</span>:<span class="hljs-number">10</span>:<span class="hljs-number">48</span> The --replicate table `<span class="javascript">radius</span>`.`<span class="javascript">checksums</span>` exists <span class="hljs-literal">on</span> the master but but it has problems <span class="hljs-literal">on</span> these <span class="hljs-attribute">replicas</span>:
  2. Table radius.checksums does <span class="hljs-keyword">not</span> exist <span class="hljs-literal">on</span> replica localhost.localdomain</code>

之前的错误,导致主从复制有问题,去从库查看主动状态,调整是得主从正常。

错误解决完了继续执行(结果有省略)

  1. <code class=" hljs r">下面继续在主库的shell上检查
  2. [root@localhost portal]<span class="hljs-comment"># pt-table-checksum h=‘192.168.1.100‘,u=‘checksums‘,p=‘slavecheck‘,P=3306 -d radius --nocheck-replication-filters --replicate=radius.checksums</span>
  3. TS ERRORS DIFFS ROWS CHUNKS SKIPPED TIME TABLE
  4. <span class="hljs-number">06</span>-16T16:<span class="hljs-number">50</span>:<span class="hljs-number">21</span> <span class="hljs-number">0</span> <span class="hljs-number">1</span> <span class="hljs-number">8379</span> <span class="hljs-number">4</span> <span class="hljs-number">0</span> <span class="hljs-number">0.322</span> radius.account_account
  5. <span class="hljs-number">06</span>-16T16:<span class="hljs-number">50</span>:<span class="hljs-number">21</span> <span class="hljs-number">0</span> <span class="hljs-number">1</span> <span class="hljs-number">11429</span> <span class="hljs-number">1</span> <span class="hljs-number">0</span> <span class="hljs-number">0.278</span> radius.account_mac
  6. <span class="hljs-number">06</span>-16T16:<span class="hljs-number">50</span>:<span class="hljs-number">21</span> <span class="hljs-number">0</span> <span class="hljs-number">1</span> <span class="hljs-number">63747</span> <span class="hljs-number">1</span> <span class="hljs-number">0</span> <span class="hljs-number">0.329</span> radius.account_smslog
  7. <span class="hljs-number">06</span>-16T16:<span class="hljs-number">50</span>:<span class="hljs-number">21</span> <span class="hljs-number">0</span> <span class="hljs-number">0</span> <span class="hljs-number">0</span> <span class="hljs-number">1</span> <span class="hljs-number">0</span> <span class="hljs-number">0.016</span> radius.auth_group
  8. <span class="hljs-number">06</span>-16T16:<span class="hljs-number">50</span>:<span class="hljs-number">21</span> <span class="hljs-number">0</span> <span class="hljs-number">0</span> <span class="hljs-number">0</span> <span class="hljs-number">1</span> <span class="hljs-number">0</span> <span class="hljs-number">0.013</span> radius.auth_group_permissions
  9. <span class="hljs-number">06</span>-16T16:<span class="hljs-number">50</span>:<span class="hljs-number">22</span> <span class="hljs-number">0</span> <span class="hljs-number">0</span> <span class="hljs-number">27</span> <span class="hljs-number">1</span> <span class="hljs-number">0</span> <span class="hljs-number">0.265</span> radius.auth_permission
  10. <span class="hljs-number">06</span>-16T16:<span class="hljs-number">50</span>:<span class="hljs-number">22</span> <span class="hljs-number">0</span> <span class="hljs-number">1</span> <span class="hljs-number">8384</span> <span class="hljs-number">1</span> <span class="hljs-number">0</span> <span class="hljs-number">0.273</span> radius.auth_user
  11. <span class="hljs-keyword">...</span>
  12. <span class="hljs-keyword">...</span></code>

出现这种结果,说明已经check了,diffs一栏有不同,说明那些表数据不一致. 现在登录从库的mysql,执行如下语句

  1. <code class=" hljs markdown">mysql> select * from radius.checksums where master<span class="hljs-emphasis">_cnt <> this_</span>cnt OR master<span class="hljs-emphasis">_crc <> this_</span>crc OR ISNULL(master<span class="hljs-emphasis">_crc) <> ISNULL(this_</span>crc) \G
  2. <span class="hljs-strong">*****</span><span class="hljs-strong">*****</span><span class="hljs-strong">*****</span><span class="hljs-strong">*****</span><span class="hljs-strong">*****</span><span class="hljs-strong">** 1. row **</span><span class="hljs-strong">*****</span><span class="hljs-strong">*****</span><span class="hljs-strong">*****</span><span class="hljs-strong">*****</span><span class="hljs-strong">*****</span>
  3. <span class="hljs-code"> db: radius</span>
  4. <span class="hljs-code"> tbl: account_account</span>
  5. <span class="hljs-code"> chunk: 2</span>
  6. <span class="hljs-code"> chunk_time: 0.028065</span>
  7. chunk_index: PRIMARY
  8. lower_boundary: 1847
  9. upper_boundary: 9225
  10. <span class="hljs-code"> this_crc: 4f43a2</span>
  11. <span class="hljs-code"> this_cnt: 7336</span>
  12. <span class="hljs-code"> master_crc: 9235f7a2</span>
  13. <span class="hljs-code"> master_cnt: 7379</span>
  14. <span class="hljs-code"> ts: 2015-06-16 17:00:31</span></code>

一共有8条记录,这8张表数据不一致。 大概能看出来缺少了多少数据等。

修复不一致数据

修复不一致数据使用pt-table-sync 工具,使用pt-table-checksum工具的结果。不过这里还是有些坑。在修复之前最好把主mysql数据备份一下,因为会对主库有些写操作,有一点风险。

主库服务器执行

  1. <code class=" hljs r">[root@localhost portal]<span class="hljs-comment"># pt-table-sync --execute --replicate radius.checksums --sync-to-master h="192.168.1.98",P=3306,u="checksums",p="slavecheck" --ignore-tables radacct,django_session</span>
  2. DBI connect(<span class="hljs-string">‘;host=124.88.52.100;port=3306;mysql_read_default_group=client‘</span>,<span class="hljs-string">‘checksums‘</span>,<span class="hljs-keyword">...</span>) failed: Access denied <span class="hljs-keyword">for</span> user <span class="hljs-string">‘checksums‘</span>@<span class="hljs-string">‘124.88.52.100‘</span> (using password: YES) at /usr/local/bin/pt-table-sync line <span class="hljs-number">2220</span>
  3. 但是直接用mysql连接就没问题</code>

最后查了下文档,发现还是用户权限的问题。
从库操作

  1. <code class=" hljs lasso">mysql<span class="hljs-subst">></span> GRANT <span class="hljs-literal">all</span> <span class="hljs-keyword">ON</span> radius<span class="hljs-built_in">.</span><span class="hljs-subst">*</span> <span class="hljs-keyword">TO</span> <span class="hljs-string">‘checksums‘</span>@<span class="hljs-string">‘192.168.1.100‘</span>;
  2. Query OK, <span class="hljs-number">0</span> <span class="hljs-keyword">rows</span> affected (<span class="hljs-number">0.00</span> sec)
  3. mysql<span class="hljs-subst">></span> flush privileges;
  4. Query OK, <span class="hljs-number">0</span> <span class="hljs-keyword">rows</span> affected (<span class="hljs-number">0.00</span> sec)</code>

主库操作

  1. <code class=" hljs lasso">mysql<span class="hljs-subst">></span> GRANT <span class="hljs-literal">all</span> <span class="hljs-keyword">ON</span> radius<span class="hljs-built_in">.</span><span class="hljs-subst">*</span> <span class="hljs-keyword">TO</span> <span class="hljs-string">‘checksums‘</span>@<span class="hljs-string">‘192.168.1.100‘</span>;
  2. Query OK, <span class="hljs-number">0</span> <span class="hljs-keyword">rows</span> affected (<span class="hljs-number">0.00</span> sec)
  3. mysql<span class="hljs-subst">></span> flush privileges;
  4. Query OK, <span class="hljs-number">0</span> <span class="hljs-keyword">rows</span> affected (<span class="hljs-number">0.00</span> sec)</code>

新增增删改查权限其实就够了 ,我这偷懒下。。

错误基本解决完了

修复数据

先修复一个不重要的表来实验下(主库操作)

  1. <code class=" hljs brainfuck"><span class="hljs-comment">pt</span><span class="hljs-literal">-</span><span class="hljs-comment">table</span><span class="hljs-literal">-</span><span class="hljs-comment">sync</span> <span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-comment">execute</span> <span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-comment">replicate</span> <span class="hljs-comment">radius</span><span class="hljs-string">.</span><span class="hljs-comment">checksums</span> <span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-comment">sync</span><span class="hljs-literal">-</span><span class="hljs-comment">to</span><span class="hljs-literal">-</span><span class="hljs-comment">master</span> <span class="hljs-comment">h=192</span><span class="hljs-string">.</span><span class="hljs-comment">168</span><span class="hljs-string">.</span><span class="hljs-comment">1</span><span class="hljs-string">.</span><span class="hljs-comment">98</span><span class="hljs-string">,</span><span class="hljs-comment">P=3306</span><span class="hljs-string">,</span><span class="hljs-comment">u=checksums</span><span class="hljs-string">,</span><span class="hljs-comment">p="slavecheck"</span> <span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-comment">tables</span> <span class="hljs-comment">account_smslog</span><span class="hljs-string">,</span><span class="hljs-comment">radcheck</span> <span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-comment">print</span> </code>

修复完成在执行一次check 主库操作

  1. <code class=" hljs lasso">pt<span class="hljs-attribute">-table</span><span class="hljs-attribute">-checksum</span> h<span class="hljs-subst">=</span><span class="hljs-string">‘192.168.1.100‘</span>,u<span class="hljs-subst">=</span><span class="hljs-string">‘checksums‘</span>,p<span class="hljs-subst">=</span><span class="hljs-string">‘slavecheck‘</span>,P<span class="hljs-subst">=</span><span class="hljs-number">3306</span> <span class="hljs-attribute">-d</span> radius <span class="hljs-subst">--</span>nocheck<span class="hljs-attribute">-replication</span><span class="hljs-attribute">-filters</span> <span class="hljs-subst">--</span>replicate<span class="hljs-subst">=</span>radius<span class="hljs-built_in">.</span>checksums</code>

在从库mysql中检查下

  1. <code class=" hljs vbnet">mysql> <span class="hljs-keyword">select</span> * <span class="hljs-keyword">from</span> radius.checksums <span class="hljs-keyword">where</span> master_cnt <> this_cnt <span class="hljs-keyword">OR</span> master_crc <> this_crc <span class="hljs-keyword">OR</span> ISNULL(master_crc) <> ISNULL(this_crc) \G</code>

的确少了2张表,说明已经修复好了

接着把其他表修复,然后检查下是否有问题就OK了。

小结

这里主要的问题就是
1 脚本在那里执行(都是在主库服务器,从库只是检查下结果)
2 怎么建立用户,用户应该给予怎样的权限

声明:
本文出自 “orangleliu笔记本” 博客,转载请务必保留此出处http://blog.csdn.net/orangleliu/article/details/46532215 作者orangleliu 采用署名-非商业性使用-相同方式共享协议

[mysql]一次主从数据不一致的问题解决过程

标签:mysql   主从   一致性   修复   

人气教程排行