91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

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

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么理解MySQL中的table_id

發布時間:2021-11-18 16:20:25 來源:億速云 閱讀:394 作者:iii 欄目:MySQL數據庫

本篇內容介紹了“怎么理解MySQL中的table_id”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

一 table_id 介紹
    當MySQL 開啟日志模式時,binlog會記錄所有對數據庫的變更操作。binlog 分兩種模式 statement 模式和row 模式。
當數據庫的binlog format 是statement 模式時
例子:數據庫中執行 一條語句
root@rac2 [yangyi]> insert into t1 values(9);                
Query OK, 1 row affected (0.00 sec)
root@rac2 [yangyi]> show binlog events in 'mysql-bin.000003';
+------------------+-----+-------------+-----------+-------------+----------------------------------------+
| Log_name         | Pos | Event_type  | Server_id | End_log_pos | Info                                   |
+------------------+-----+-------------+-----------+-------------+----------------------------------------+
| mysql-bin.000003 |   4 | Format_desc |         2 |         106 | Server ver: 5.1.68-log, Binlog ver: 4  |
| mysql-bin.000003 | 106 | Query       |         2 |         176 | BEGIN                                  |
| mysql-bin.000003 | 176 | Query       |         2 |         265 | use `yangyi`; insert into t1 values(8) |
| mysql-bin.000003 | 265 | Xid         |         2 |         292 | COMMIT /* xid=12 */                    |
| mysql-bin.000003 | 292 | Query       |         2 |         369 | use `yangyi`; flush tables             |
| mysql-bin.000003 | 369 | Query       |         2 |         439 | BEGIN                                  |
| mysql-bin.000003 | 439 | Query       |         2 |         528 | use `yangyi`; insert into t1 values(9) |
| mysql-bin.000003 | 528 | Xid         |         2 |         555 | COMMIT /* xid=15 */                    |
+------------------+-----+-------------+-----------+-------------+----------------------------------------+
8 rows in set (0.00 sec)
binlog 的log event 記錄如下:
#140511 14:44:12 server id 2  end_log_pos 439   Query   thread_id=1     exec_time=0     error_code=0
SET TIMESTAMP=1399790652/*!*/;
BEGIN
/*!*/;
# at 439
#140511 14:44:12 server id 2  end_log_pos 528   Query   thread_id=1     exec_time=0     error_code=0
SET TIMESTAMP=1399790652/*!*/;
insert into t1 values(9)
/*!*/;
# at 528
#140511 14:44:12 server id 2  end_log_pos 555   Xid = 15
COMMIT/*!*/;
從日志分析來看 ,DML會記錄為原始的SQL,也就是記錄在QUERY_EVENT中。 

當數據庫的binlog format 是row模式時
執行insert 操作
root@rac2 [yangyi]> insert into t1 values(6);                
Query OK, 1 row affected (0.00 sec)
root@rac2 [yangyi]> show binlog events in 'mysql-bin.000002';          
+------------------+-----+-------------+-----------+-------------+---------------------------------------+
| Log_name         | Pos | Event_type  | Server_id | End_log_pos | Info                                  |
+------------------+-----+-------------+-----------+-------------+---------------------------------------+
| mysql-bin.000002 |   4 | Format_desc |         2 |         106 | Server ver: 5.1.68-log, Binlog ver: 4 |
| mysql-bin.000002 | 106 | Query       |         2 |         176 | BEGIN                                 |
| mysql-bin.000002 | 176 | Table_map   |         2 |         219 | table_id: 18 (yangyi.t1)              |
| mysql-bin.000002 | 219 | Write_rows  |         2 |         253 | table_id: 18 flags: STMT_END_F        |
| mysql-bin.000002 | 253 | Xid         |         2 |         280 | COMMIT /* xid=61 */                   |
+------------------+-----+-------------+-----------+-------------+---------------------------------------+
5 rows in set (0.00 sec)
binlog中記錄的信息:
BEGIN
/*!*/;
# at 176
# at 219
#140511 14:31:43 server id 2  end_log_pos 219   Table_map: `yangyi`.`t1` mapped to number 18
#140511 14:31:43 server id 2  end_log_pos 253   Write_rows: table id 18 flags: STMT_END_F
BINLOG '
TxlvUxMCAAAAKwAAANsAAAAAABIAAAAAAAEABnlhbmd5aQACdDEAAQMAAQ==
TxlvUxcCAAAAIgAAAP0AAAAAABIAAAAAAAEAAf/+BgAAAA==
'/*!*/;
### INSERT INTO `yangyi`.`t1`
### SET
###   @1=6 /* INT meta=0 nullable=1 is_null=0 */
# at 253
#140511 14:31:43 server id 2  end_log_pos 280   Xid = 61
COMMIT/*!*/;
   從解析的binlog中可以看出row模式下,DML操作會記錄為:TABLE_MAP_EVENT+ROW_LOG_EVENT(包括WRITE_ROWS_EVENT ,UPDATE_ROWS_EVENT,DELETE_ROWS_EVENT).
   為什么一個update在ROW模式下需要分解成兩個event:一個Table_map,一個Update_rows。我們想象一下,一個update如果更新了10000條數據,那么對應的表結構信息是否需要記錄10000次?其實是對同一個表的操作,所以這里binlog只是記錄了一個Table_map用于記錄表結構相關信息,而后面的Update_rows記錄了更新數據的行信息。他們之間是通過table_id來聯系的。 

二 table_id 的特性
  1 table_id 并不是固定的,它是當表被載入內存(table_definition_cache)時,臨時分配的,是一個不斷增長的變量。  
  2 當有新的table變更時,在cache中沒有,就會觸發一次load table def的操作,此時就會在原先最后一次table_id基礎上+1,做為新的table def的id。
  3 flush tables,之后對表的更新操作也會觸發table_id 的增長。
  4 如果table def cache過小,就會出現頻繁的換入換出,從而導致table_id增長比較快。
例子
root@rac2 [yangyi]> show binlog events in 'mysql-bin.000002';
+------------------+-----+-------------+-----------+-------------+---------------------------------------+
| Log_name         | Pos | Event_type  | Server_id | End_log_pos | Info                                  |
+------------------+-----+-------------+-----------+-------------+---------------------------------------+
| mysql-bin.000002 |   4 | Format_desc |         2 |         106 | Server ver: 5.1.68-log, Binlog ver: 4 |
| mysql-bin.000002 | 106 | Query       |         2 |         176 | BEGIN                                 |
| mysql-bin.000002 | 176 | Table_map   |         2 |         219 | table_id: 18 (yangyi.t1)              |
| mysql-bin.000002 | 219 | Write_rows  |         2 |         253 | table_id: 18 flags: STMT_END_F        |
| mysql-bin.000002 | 253 | Xid         |         2 |         280 | COMMIT /* xid=61 */                   |
| mysql-bin.000002 | 280 | Query       |         2 |         357 | use `yangyi`; flush tables            |
| mysql-bin.000002 | 357 | Query       |         2 |         427 | BEGIN                                 |
| mysql-bin.000002 | 427 | Table_map   |         2 |         470 | table_id: 19 (yangyi.t1)              |
| mysql-bin.000002 | 470 | Write_rows  |         2 |         504 | table_id: 19 flags: STMT_END_F        |
| mysql-bin.000002 | 504 | Xid         |         2 |         531 | COMMIT /* xid=65 */                   |
+------------------+-----+-------------+-----------+-------------+---------------------------------------+
10 rows in set (0.00 sec)

三 table_id在主從復制過程中轉變  
     每一個dml操作表的信息都被會記錄table_mapping的hash數據結構中,hash的key就是ulong型的table_id,hash的值就是TABLE*的數據結構(包含了表的各種信息,包括數據庫名,表名,字段數,字段類型等),通過set_table()方法來hash,通過get_table()方法來根據table_id獲得對應的表信息。
    當主庫的日志傳遞到備庫時,每一個log_event都是通過do_apply_event()方法來將event應用到本地數據庫中。在apply relay log中的event時,do_apply_event()將ulong型的m_table_id(binlog記錄的table_id)賦值給RPL_TABLE_LIST結構中的uint型的table_id。核心問題出現了: 如果binlog 中的table_id 的值大于max(uint),在變量傳遞是,就會發生截斷。
而MySQL內部使用set_table(table_id)構造hash,使用get_table(m_table_id)從hash表中取值,在兩個階段用到的key因為發生了數據截斷,所以必然也就不能取到預期的值。也就是說之前用uint型的table_id構建出來的key-value的hash對,用ulong型的m_table_id是無法查詢到的。

四 風險與解決
  從第二,三點我們知道當table_id 過快增長,會導致從庫應用binlog無法解析到對應的表,造成數據不一致的情況。
解決方法:
 1 加大 table cache 的大小。
 2 重啟主庫使table_id 歸0,缺點 成本比較高,出現此問題的時候,主備已經不一致,線上環境 不能完成切換。
 3 修改MySQL源碼,將 RPL_TABLE_LIST結構中的uint型的table_id修改為ulong型 ,一勞永逸。

“怎么理解MySQL中的table_id”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

花垣县| 阜康市| 德格县| 榆中县| 新邵县| 马公市| 和政县| 左贡县| 册亨县| 珠海市| 济阳县| 普陀区| 合作市| 弋阳县| 麻栗坡县| 汨罗市| 渭南市| 阿城市| 石阡县| 永康市| 陆良县| 靖远县| 黑山县| 芦溪县| 永定县| 博爱县| 治县。| 仁寿县| 江北区| 尉氏县| 句容市| 兰西县| 奎屯市| 蓬溪县| 常熟市| 葵青区| 宁明县| 绥滨县| 南投县| 曲阜市| 泗洪县|