溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

MySQL中GTID的幾個(gè)限制和解決方案是怎樣的

發(fā)布時(shí)間:2021-09-26 15:01:00 來(lái)源:億速云 閱讀:172 作者:柒染 欄目:MySQL數(shù)據(jù)庫(kù)

本篇文章給大家分享的是有關(guān)MySQL中GTID的幾個(gè)限制和解決方案是怎樣的,小編覺(jué)得挺實(shí)用的,因此分享給大家學(xué)習(xí),希望大家閱讀完這篇文章后可以有所收獲,話不多說(shuō),跟著小編一起來(lái)看看吧。

   現(xiàn)在我看待一個(gè)技術(shù),總是會(huì)換一種角度來(lái)看,在他能實(shí)現(xiàn)什么的基礎(chǔ)上,我更喜歡看他不能做什么,為什么不能這么做。

   比如MySQL GTID在5.6試水,5.7已經(jīng)發(fā)展完善,但是還是有一些場(chǎng)景是受限的。比如下面的兩個(gè)。

    一個(gè)是create table xxx as select 的模式,另外一個(gè)是臨時(shí)表相關(guān)的。

MySQL中GTID的幾個(gè)限制和解決方案是怎樣的

   今天我們就來(lái)簡(jiǎn)單說(shuō)說(shuō)這兩個(gè)場(chǎng)景。

GTID中create 語(yǔ)句限制的解法

   create table xxx as select的語(yǔ)句,其實(shí)會(huì)被拆分為兩部分,create語(yǔ)句和insert語(yǔ)句,但是如果想一次搞定,MySQL會(huì)拋出如下的錯(cuò)誤。

mysql> create table test_new as select *from test;
ERROR 1786 (HY000): Statement violates GTID consistency: CREATE TABLE ... SELECT.

   這種語(yǔ)句其實(shí)目標(biāo)明確,復(fù)制表結(jié)構(gòu),復(fù)制數(shù)據(jù),insert的部分好解決,難點(diǎn)就在于create table的部分,如果一個(gè)表的列有100個(gè),那么拼出這么一個(gè)語(yǔ)句來(lái)就是一個(gè)工程了。

    我們也巧學(xué)巧用,看看MySQL有什么特別的方法來(lái)處理。

    除了規(guī)規(guī)矩矩的拼出建表語(yǔ)句之外,還有一個(gè)方法是MySQL特有的用法 like。

    create table xxx as select 的方式會(huì)被拆分成兩部分。

 create table xxxx like data_mgr;
 insert into xxxx select *from data_mgr;

臨時(shí)表的限制和考慮

   另外一個(gè)看起來(lái)就有些蹊蹺了,看著文檔就是沒(méi)有什么好說(shuō)的,記住了就好,其實(shí)不然。

    如果在事務(wù)中有臨時(shí)表的變動(dòng),很可能會(huì)導(dǎo)致數(shù)據(jù)不一致,這在MySQL的5.5版本中有相應(yīng)的bug,可以參見(jiàn)https://bugs.mysql.com/bug.php?id=76940

     如果需要復(fù)現(xiàn),可以在找一套5.5的環(huán)境來(lái)模擬一下,分分鐘出效果。

    我們創(chuàng)建兩個(gè)表t1,t2,然后建立兩個(gè)表之間的外鍵關(guān)聯(lián),作為 后續(xù)測(cè)試所用。

create table t1(c1 int primary key)  engine=innodb;
insert into t1 values(1),(2),(3),(4),(5);
create table t2 (c1 int, c2 int, foreign key(c2) references t1(c1)) engine=innodb;
insert into t2 values(1,1),(2,2),(5,5);  

 創(chuàng)建臨時(shí)表

> create temporary table tmp as select * from t1;
Query OK, 5 rows affected (0.01 sec)
Records: 5  Duplicates: 0  Warnings: 0

模擬這個(gè)bug,開(kāi)啟事務(wù)。

> begin;
> drop temporary table if exists tmp;
Query OK, 0 rows affected (0.00 sec)
> delete from t1 where c1 > 2;
ERROR 1451 (23000): Cannot delete or update a parent row: a fore;
Query OK, 0 rows affected (0.00 sec)

然后使用mysqlbinlog來(lái)查看一下里面的信息??梢钥吹匠松厦娴呐R時(shí)表操作,后面的delete也會(huì)寫(xiě)入binlog

use `test`/*!*/;
SET TIMESTAMP=1499784283/*!*/;
DROP TEMPORARY TABLE IF EXISTS `tmp` /* generated by server */
/*!*/;
# at 300
# at 341
#170711 22:44:46 server id 13386  end_log_pos 341       Table_map: `test`.`t1` mapped to number 207
#170711 22:44:46 server id 13386  end_log_pos 380       Delete_rows: table id 207 flags: STMT_END_F

BINLOG '
XuRkWRNKNAAAKQAAAFUBAAAAAM8AAAAAAAEABHRlc3QAAnQxAAEDAAA=
XuRkWRlKNAAAJwAAAHwBAAAAAM8AAAAAAAEAAf/+AwAAAP4EAAAA
'/*!*/;
### DELETE FROM test.t1
### WHERE
###   @1=3 /* INT meta=0 nullable=0 is_null=0 */
### DELETE FROM test.t1
### WHERE
###   @1=4 /* INT meta=0 nullable=0 is_null=0 */
# at 380
#170711 22:44:49 server id 13386  end_log_pos 449       Query   thread_id=176   exec_time=0     error_code=0
SET TIMESTAMP=1499784289/*!*/;
COMMIT

   通過(guò)這個(gè)可以清晰的看到盡管已經(jīng)做了事務(wù)回滾,但是binlog還是會(huì)記錄下回滾的變更,這在某些場(chǎng)景中會(huì)觸發(fā)主從數(shù)據(jù)不一致。

   而在GTID中,已經(jīng)做了這個(gè)檢查,歸根結(jié)底,還是cache里面的機(jī)制,大體來(lái)說(shuō),binlog有兩個(gè)cache來(lái)緩存事務(wù)的binlog:

  binlog_cache_data stmt_cache; //存放非事務(wù)表和臨時(shí)表binlog
  binlog_cache_data trx_cache;  //存放事務(wù)表binlog

以上就是MySQL中GTID的幾個(gè)限制和解決方案是怎樣的,小編相信有部分知識(shí)點(diǎn)可能是我們?nèi)粘9ぷ鲿?huì)見(jiàn)到或用到的。希望你能通過(guò)這篇文章學(xué)到更多知識(shí)。更多詳情敬請(qǐng)關(guān)注億速云行業(yè)資訊頻道。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI