1. 程式人生 > >讓天下沒有難用的資料庫 » 主備不一致:Table definition on master and slave does not match

讓天下沒有難用的資料庫 » 主備不一致:Table definition on master and slave does not match

主備不一致:Table definition on master and slave does not match

昨天一同事在線上做變更,為了保證主庫的穩定性,先在備庫把binlog關閉,然後在進行DDL變更,在通過切換HA,把備庫切換為主庫,在老的主庫上做DDL變更 看上去這樣做法沒有太大的問題,但是當備庫變更一做完,HA切換到備庫,開始老主庫變更的時候,備庫就出現複製出現錯誤: Last_Error: Table definition on master and slave does not match: Column 10 type mismatch – received type 3, dbname.table_name has type 8
Skip_Counter: 0 Exec_Master_Log_Pos: 1046252634 Relay_Log_Space: 2910773181 Until_Condition: None Until_Log_File: Until_Log_Pos: 0 Master_SSL_Allowed: No Master_SSL_CA_File: Master_SSL_CA_Path: Master_SSL_Cert: Master_SSL_Cipher: Master_SSL_Key: Seconds_Behind_Master: NULL Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0 Last_IO_Error: Last_SQL_Errno: 1535 Last_SQL_Error: Table definition on master and slave does not match: Column 10 type mismatch – received type 3, dbname.table_name has type 8 1 row in set (0.00 sec) <1>從這個錯誤上來看,是主備的表結構不一致導致的,但是之前的複製都是好好的,為什麼做完變更後就會出現這個問題,應該是在DDL變更後導致的問題; master:
mysql -uroot dbname -e “show create table table_name”>master.sql slave: mysql -uroot dbname -e “show create table table_name”>slave.sql diff -u master.sql slave.sql沒有找到兩個表結構有什麼大問題; <2>查看出問題的資料欄位: [email protected] : dbname 17:46:35> desc table_name; +—————-+———————+——+—–+——————-+—————————–+ | Field | Type | Null | Key | Default | Extra | +—————-+———————+——+—–+——————-+—————————–+ | url | varchar(333) | NO | UNI | NULL | | | Description | varchar(255) | YES | | NULL | | | HttpStatus | int(11) | YES | | NULL | | | AddTime | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP | | ServerBanner | varchar(255) | YES | | NULL | | | TaskTag | varchar(255) | NO | MUL | NULL | | | TaskTag2 | varchar(255) | YES | | NULL | | | DomainName | varchar(255) | NO | MUL | NULL | | | R_DomainName | varchar(255) | YES | MUL | NULL | | | ScanTaskID | int(11) | YES | | NULL | | | SubTaskID | bigint(20) unsigned | NO | PRI | NULL | auto_increment | | urlhash | varchar(32) | YES | UNI | | | | duplicateHash | varchar(32) | YES | | | | | enable | tinyint(1) | YES | | 0 | | | webappid | int(11) | YES | | NULL | | | crc_DomainName | int(10) unsigned | YES | MUL | NULL | | | wapscore | int(11) | YES | | 0 | | | ip | varchar(45) | YES | | NULL | | +—————-+———————+——+—–+——————-+—————————–+ slave: [email protected] : information_schema 14:59:40> select * from columns where table_schema=”dbname” and table_name=”table_name” and ORDINAL_POSITION= 10\G; *************************** 1. row *************************** TABLE_CATALOG: NULL TABLE_SCHEMA: dbname TABLE_NAME: table_name COLUMN_NAME: ScanTaskID ORDINAL_POSITION: 10 COLUMN_DEFAULT: NULL IS_NULLABLE: YES DATA_TYPE: int CHARACTER_MAXIMUM_LENGTH: NULL CHARACTER_OCTET_LENGTH: NULL NUMERIC_PRECISION: 10 NUMERIC_SCALE: 0 CHARACTER_SET_NAME: NULL COLLATION_NAME: NULL COLUMN_TYPE: int(11) COLUMN_KEY: EXTRA: PRIVILEGES: select,insert,update,references COLUMN_COMMENT: 1 row in set (0.00 sec) master: [email protected] : information_schema 14:59:19> select * from information_schema.columns where table_schema=”dbname” and table_name=”table_name” and ORDINAL_POSITION= 10\G; *************************** 1. row *************************** TABLE_CATALOG: NULL TABLE_SCHEMA: dbname TABLE_NAME: table_name COLUMN_NAME: ScanTaskID ORDINAL_POSITION: 10 COLUMN_DEFAULT: NULL IS_NULLABLE: YES DATA_TYPE: int CHARACTER_MAXIMUM_LENGTH: NULL CHARACTER_OCTET_LENGTH: NULL NUMERIC_PRECISION: 10 NUMERIC_SCALE: 0 CHARACTER_SET_NAME: NULL COLLATION_NAME: NULL COLUMN_TYPE: int(11) COLUMN_KEY: EXTRA: PRIVILEGES: select,insert,update,references COLUMN_COMMENT: 1 row in set (0.00 sec) 檢視資料欄位,主備庫還是一致的,這個時候好像到了窮途; <3>檢視同事昨天的DDL變更指令碼,涉及到加欄位,調整欄位的長度,看上去很平常, 我們是先在備庫做的變更,然後在到主庫的變更,期間的binlog是關閉的,這時候,印風同學想到如果在備庫變更的時候,主庫的業務是沒有停止的, 如果主庫變更的資料同步到備庫,備庫的變更做完,主備已經不一致了,這樣的話,就會造成複製失敗了,看了看指令碼中有欄位長度調長的,這下就迎刃而解了; 問了一下B2B的plinux,他們只有加欄位的時候,才放到備庫上去做,其他的還是在主庫上直接做的; <4>剛才看到從 information_schema.columns 中查詢有問題的列的時候,直接代入ORDINAL_POSITION= 10得到的是ScanTaskID 欄位,但出問題的欄位是第11為欄位(即我們調整長度的欄位),所以binlog中是從0開始計算欄位的位置的; <5>5.5中報錯顯得更加人性了: Column 0 of table ‘test.t3’ cannot be converted from type ‘int’ to type ‘bigint(20)’; <6>.那如何避免這樣的問題喃,由於我們的庫採用的是row模式,只要把slave的複製改為statement就可以了,將主庫的binlog_format由row改為statement,這樣達到備庫的binlog就不會出現錯誤; Categories: Tags: