避免pxc集群全局锁

来源:这里教程网 时间:2026-03-01 15:38:24 作者:
首先我们知道pxc集群为了获得全局一致性gtid,当你执行ddl操作的时候,他会上全局锁,会阻塞后面整个实例所有的dml或者ddl操作;然后不产生全局gtid,是不是就不会上全局锁了呢?如果是这样的话,修改pxc的一个非热表的时候,可以通过这样方式来避免全局锁了!
一.查看pxc集群当前节点最新提交的事务号;
他是最新的galera GTID的后半部分,前半部分是状态变量wsrep_local_state_uuid的值,每次事务提交、ddl完成或apply完成之后都会更新这个值
root@localhost : liuwenhe 17:39:09>show  status  like  'wsrep_last_committed';
+----------------------+--------+
| Variable_name        | Value  |
+----------------------+--------+
| wsrep_last_committed | 607126 |
+----------------------+--------+
二.如下查看的pxc集群的全局gtid的前半部分,注意这个值和文件grastate.dat中的uuid值保持一致!
root@localhost : (none) 17:57:13>show  status  like   'wsrep_local_state_uuid';
+------------------------+--------------------------------------+
| Variable_name          | Value                                |
+------------------------+--------------------------------------+
| wsrep_local_state_uuid | 3b7d95fe-57e3-11eb-aa7b-126de221ca40 |
+------------------------+--------------------------------------+
1 row in set (0.01 sec)
三.如下查看到的是本地的节点的gtid值,注意这里的uuid值主从同步需要的gtid,需要注意的是pxc集群各个节点有可能是不一样的;
root@localhost : liuwenhe 17:39:15>show  master  status;
+------------------+----------+--------------+------------------+-----------------------------------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set                             |
+------------------+----------+--------------+------------------+-----------------------------------------------+
| mysql-bin.000011 | 94721093 |              |                  | c4826a01-a81c-ee14-5584-ed921dde35bf:1-607120 |
+------------------+----------+--------------+------------------+-----------------------------------------------+
四、当你关闭binlog或者关闭pxc集群广播后,那么该节点是不会产生gtid的(包括pxc集群的全局gtid,以及本地show master  status都不会产生),如下所示:
set sql_log_bin=OFF;
set @@session.wsrep_on = OFF;
实验过程:
节点1:
4.1:关闭binlog以及同步(pxc一般删除大表的时候需要这样设置然后逐个节点操作)
root@localhost : (none) 18:04:21>set sql_log_bin=OFF;
Query OK, 0 rows affected (0.00 sec)
root@localhost : (none) 18:05:15>set @@session.wsrep_on = OFF;
Query OK, 0 rows affected (0.00 sec)
4.2:查看此时该节点的本地gtid的信息;
root@localhost : (none) 18:05:16>show  master  status;
+------------------+-----------+--------------+------------------+---------------------------------------------------------------
| File             | Position  | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set                                                                       |
+------------------+-----------+--------------+------------------+---------------------------------------------------------------
| mysql-bin.000012 | 102594983 |      |c4826a01-a81c-ee14-5584-ed921dde35bf:1- 607121 |
+------------------+-----------+--------------+------------------+---------------------------------------------------------------
4.3:查看此时的该节点上PXC全局gtid的后半部分,也就是xid的信息(注意这个值是保证集群各个节点数据一致的关键)
root@localhost : (none) 18:05:23>show  status  like  'wsrep_last_committed';
+----------------------+--------+
| Variable_name        | Value  |
+----------------------+--------+
| wsrep_last_committed | 607126 |
+----------------------+--------+
1 row in set (0.00 sec)
4.4:然后执行事务
root@localhost : liuwenhe 18:13:39>alter table  liuwenhe3 add  liud int;
Query OK, 0 rows affected (0.02 sec)
Records: 0  Duplicates: 0  Warnings: 0
4.5 再次查看pxc集群的全局gtid以及节点自己的gtid
root@localhost : (none) 18:05:16>show  master  status;
+------------------+-----------+--------------+------------------+---------------------------------------------------------------
| File             | Position  | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set                                                                       |
+------------------+-----------+--------------+------------------+---------------------------------------------------------------
| mysql-bin.000012 | 102594983 |      |c4826a01-a81c-ee14-5584-ed921dde35bf:1- 607121 |
+------------------+-----------+--------------+------------------+---------------------------------------------------------------
root@localhost : (none) 18:05:23>show  status  like  'wsrep_last_committed';
+----------------------+--------+
| Variable_name        | Value  |
+----------------------+--------+
| wsrep_last_committed | 607126 |
+----------------------+--------+
1 row in set (0.00 sec)
如下截图为正常执行事务,会导致gtid以及pxc全局gtid后面部分的xid加1
如下截图为 关闭binlog并且关闭pxc集群广播参数,那么该节点是不会产生gtid的(包括pxc集群的全局gtid,以及本地show master  status都不会产生)
五、只关闭pxc广播的参数,会发现全局gtid不变化,但是本地的gtid会记录一个新uuid的gtid!并且从1开始的!这就会保证该节点上的slave库,是可以同步该操作的!
实验记录:
root@localhost : liuwenhe 21:44:15>set @@session.wsrep_on = OFF;
Query OK, 0 rows affected (0.00 sec)
root@localhost : liuwenhe 21:44:21>show  status  like  'wsrep_last_committed';
+----------------------+--------+
| Variable_name        | Value  |
+----------------------+--------+
| wsrep_last_committed | 607130 |
+----------------------+--------+
1 row in set (0.00 sec)
root@localhost : liuwenhe 21:44:24>show  master  status;
+------------------+----------+--------------+------------------+-----------------------------------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set                             |
+------------------+----------+--------------+------------------+-----------------------------------------------+
| mysql-bin.000011 | 94721825 |              |                  | c4826a01-a81c-ee14-5584-ed921dde35bf:1-607124 |
+------------------+----------+--------------+------------------+-----------------------------------------------+
1 row in set (0.00 sec)
执行事务:
root@localhost : liuwenhe 21:44:29>alter  table  liuwenhe.liuwenhe3 add liud234 int;
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0
再次查看发现本地的gtid产生了一个新的名字为80a906d0-5891-11eb-a103-005056a3f3aa:1的gtid
root@localhost : liuwenhe 21:44:37>show  master  status;
+------------------+----------+--------------+------------------+---------------------------------------------------------------------------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set                                                                     |
+------------------+----------+--------------+------------------+---------------------------------------------------------------------------------------+
| mysql-bin.000011 | 94722020 |              |                  | 80a906d0-5891-11eb-a103-005056a3f3aa:1,
c4826a01-a81c-ee14-5584-ed921dde35bf:1-607124 |
+------------------+----------+--------------+------------------+---------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
再次执行事务
root@localhost : liuwenhe 21:44:39>alter  table  liuwenhe.liuwenhe3 modify  liud234 int;
Query OK, 0 rows affected (0.00 sec)
Records: 0  Duplicates: 0  Warnings: 0
发现本地新产生的gtid为:80a906d0-5891-11eb-a103-005056a3f3aa:1-2,事务为1-2了!
root@localhost : liuwenhe 21:45:12>show  master  status;
+------------------+----------+--------------+------------------+-----------------------------------------------------------------------------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set                                                                       |
+------------------+----------+--------------+------------------+-----------------------------------------------------------------------------------------+
| mysql-bin.000011 | 94722219 |              |                  | 80a906d0-5891-11eb-a103-005056a3f3aa:1-2,
c4826a01-a81c-ee14-5584-ed921dde35bf:1-607124 |
+------------------+----------+--------------+------------------+-----------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
但是查看pxc全局gtid,发现全局gtid没变化;
root@localhost : liuwenhe 21:45:14>show  status  like  'wsrep_last_committed';
+----------------------+--------+
| Variable_name        | Value  |
+----------------------+--------+
| wsrep_last_committed | 607130 |
+----------------------+--------+
1 row in set (0.00 sec)
六、只关闭binlog,会发现全局gtid不变化,但是本地的gtid也不变化!这样的话集群其他节点以及他的slave库都不会同步后面的操作!
root@localhost : (none) 22:05:04>set sql_log_bin=OFF;
Query OK, 0 rows affected (0.00 sec)
root@localhost : (none) 22:05:25>show  master  status;
+------------------+----------+--------------+------------------+-----------------------------------------------------------------------------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set                                                                       |
+------------------+----------+--------------+------------------+-----------------------------------------------------------------------------------------+
| mysql-bin.000011 | 94722219 |              |                  | 80a906d0-5891-11eb-a103-005056a3f3aa:1-2,
c4826a01-a81c-ee14-5584-ed921dde35bf:1-607124 |
+------------------+----------+--------------+------------------+-----------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
root@localhost : (none) 22:05:41>show  status  like  'wsrep_last_committed';
+----------------------+--------+
| Variable_name        | Value  |
+----------------------+--------+
| wsrep_last_committed | 607130 |
+----------------------+--------+
1 row in set (0.01 sec)
root@localhost : (none) 22:06:02>alter  table  liuwenhe.liuwenhe3 modify  liud234 int;
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0
发现全局gtid不变化
root@localhost : (none) 22:06:14>show  status  like  'wsrep_last_committed';
+----------------------+--------+
| Variable_name        | Value  |
+----------------------+--------+
| wsrep_last_committed | 607130 |
+----------------------+--------+
1 row in set (0.01 sec)
发现本地gtid也不变化
root@localhost : (none) 22:06:18>show  master  status;
+------------------+----------+--------------+------------------+-----------------------------------------------------------------------------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set                                                                       |
+------------------+----------+--------------+------------------+-----------------------------------------------------------------------------------------+
| mysql-bin.000011 | 94722219 |              |                  | 80a906d0-5891-11eb-a103-005056a3f3aa:1-2,
c4826a01-a81c-ee14-5584-ed921dde35bf:1-607124 |
+------------------+----------+--------------+------------------+-----------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
七:pxc集群为了得到全局一致的gtid,ddl操作会加全局锁,堵塞其他所有dml和ddl操作!那么当节点不产生全局gtid的时候,理论上就不产生全局锁了,根据前面的测试可以知道如下两个命令,会让节点上的操作不产生全局gtid, 那么我们就验证下我们的猜想!
set @@session.wsrep_on = OFF;
set sql_log_bin=OFF;
实验结果:
session1:因为测试环境没有大表,alter操作特别快,所以为了实验效果,我模拟了一个alter等待元数据锁导致,进而模拟长时间的alter!
root@localhost : (none) 22:28:34>begin;
Query OK, 0 rows affected (0.00 sec)
root@localhost : (none) 22:28:54>select * from  liuwenhe.liuwenhe for  update;
Empty set (0.00 sec)
session2:执行alter这个表,她会等待元数据锁,首先先关闭pxc广播的参数!
set @@session.wsrep_on = OFF;   或者set sql_log_bin=OFF; #结果一样
root@localhost : (none) 22:29:36>alter  table  liuwenhe.liuwenhe  add  id5 int;
session3:尝试dml操作,发现是可以的!这说明session2的ddl操作没有产生全局锁!
root@localhost : liuwenhe 22:42:08>insert  into  liuwenhe.liuwenhe2 values (2);
Query OK, 1 row affected (0.00 sec)
证明当不产生全局gtid的时候,自然也就不会有全局锁,
同样如果你在某个节点,如下方式删除大表,那么是不会影响其他节点的dml操作的,因为没有全局锁!
set @@session.wsrep_on = OFF;
set sql_log_bin=OFF;
drop table  大表;
综上所述:
1)注意pxc集群的全局gtid和集群节点本地的gtid是两回事,他们的xid(gtid的后半部分)是可能不一样的,具体见实验一、二、三的说明!
2)set @@session.wsrep_on = OFF和set sql_log_bin=OFF;的区别
首先两个命令后,都不会产生全局gtid,也就是说执行了这俩命令后,之后的操作不会同步到其他节点,也就是会造成节点之间的数据不一致;虽然wsrep_on = OFF之后的操作不会给其他节点广播同步,但是依旧会同步到从库,因为他会产生一个新的gtid(具体见实验五);sql_log_bin=OFF执行这个之后,全局gtid不产生,本地gtid也不变化,这样的话,既不会给其他节点广播数据,也不会同步到从库(见实验六);
3)set @@session.wsrep_on = OFF和set sql_log_bin=OFF;都不产生全局gtid,那么也就不会有全局锁,ddl操作就不会阻塞全局事务,可以理解为把该节点降级为普通的percona单节点了!
所以如果你在某个节点,如下方式删除大表,那么是不会影响其他节点的dml操作的,因为没有全局锁!核心思想是没有产生全局gtid,所以不需要上全局锁!
set @@session.wsrep_on = OFF;
set sql_log_bin=OFF;
drop table  大表;

相关推荐