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

溫馨提示×

溫馨提示×

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

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

pt-archiver和自增主鍵的問題怎么解決

發布時間:2022-04-25 13:51:18 來源:億速云 閱讀:143 作者:iii 欄目:開發技術

今天小編給大家分享一下pt-archiver和自增主鍵的問題怎么解決的相關知識點,內容詳細,邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。

前言

pt-archiver 是一款常見的 表清理或者歸檔工具。

MySQL 中刪除大表之前可以使用 pt-archiver 批量刪除所有記錄。這樣助于避免在某些情況下您的服務器可能會意外的情況,比如磁盤 IO 滿導致數據庫hang或者影響正常 SQL 慢查。

問題 "使用 pt-archiver  刪除數據時,最后一行數據未被刪除。這個是不是bug?"

分析

在解決客戶的問題之前,我們需要解釋為什么在刪除大表之前使用 pt-archiver 當我們在 MySQL 中刪除一個表時, MySQL 系統會做如下動作:

刪除表數據/索引 (ibd) 和定義 (frm) 文件。
刪除觸發器。
通過刪除要刪除的表來更新表定義緩存。
掃描 InnoDB 緩沖池以查找關聯頁面以使其無效。--內存到的表會遇到系統hang。

需要注意的是,DROP 是一個 DDL 語句,它需要持有元數據鎖 (MDL) 才能完成,這樣會導致所有其他線程必須等待DDL完成,清除表相關的大量數據頁會對緩沖池產生額外的壓力。

最后,table_definition_cache 操作需要 LOCK_open mutex 來清理,這會導致所有其他線程等待直到刪除完成。

為了降低此操作的嚴重性,我們可以使用 pt-archiver 通過批量的形式刪除大量數據,從而顯著降低表大小。一旦我們從大表中刪除了記錄,DROP 操作就會快速進行而不會對系統性能產生影響。

社區成員注意到此行為,在 pt-archiver 完成后,該表仍有一行待處理。

# Created table
mysql> CREATE TABLE `tt1` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `a` char(5) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB

# Poured random test data into it
mysql> call populate('test','att1',10000,'N');

# Purged data using pt-archiver
[root@centos_2 ~]# pt-archiver --source=h=localhost,D=test,t=tt1 --purge --where "1=1"

# Verifying count (expected 0, got 1)
mysql> select count(*) from test.tt1;
+----------+
| count(*) |
+----------+
|        1 |
+----------+
1 row in set (0.00 sec)

當我們使用帶有 --no-delete 參數的 pt-archiver 進行數據歸檔時,也會發生同樣的情況。我們的工具 pt-archiver 似乎沒有將最大值復制到目標表。

將表從 tt1 遷移到 tt2 
[root@centos_2 ~]# pt-archiver --source=h=localhost,D=test,t=tt1 --dest=h=localhost,D=test,t=tt2 --no-delete --where "1=1"

mysql> select count(*) from tt2;
+----------+
| count(*) |
+----------+
|     5008 |
+----------+
1 row in set (0.00 sec)

mysql> select count(*) from tt1;
+----------+
| count(*) |
+----------+
|     5009 |
+----------+
1 row in set (0.00 sec)

解析

通讀 pt-archiver 文檔,有一個選項 –[no]safe-auto-increment 描述了用法:“不要使用 max AUTO_INCREMENT 歸檔行。”

這意味著,選項 –safe-auto-increment(默認)添加了一個額外的 WHERE 子句,以防止 pt-archiver 在提升單列 AUTO_INCREMENT 時刪除最新的行,如下面的代碼部分所示:

https://github.com/percona/percona-toolkit/blob/3.x/bin/pt-archiver#L6449
   if ( $o->get('safe-auto-increment')
         && $sel_stmt->{index}
         && scalar(@{$src->{info}->{keys}->{$sel_stmt->{index}}->{cols}}) == 1
         && $src->{info}->{is_autoinc}->{
            $src->{info}->{keys}->{$sel_stmt->{index}}->{cols}->[0]
         }
   ) {
      my $col = $q->quote($sel_stmt->{scols}->[0]);
      my ($val) = $dbh->selectrow_array("SELECT MAX($col) FROM $src->{db_tbl}");
      $first_sql .= " AND ($col < " . $q->quote_val($val) . ")";
   }

讓我們通過空運行輸出看看這兩個命令之間的區別:

# With --no-safe-auto-increment
[root@centos_2 ~]# pt-archiver --source=h=localhost,D=test,t=tt1 --dest=h=localhost,D=test,t=tt2 --no-delete --where "1=1" <strong>--no-safe-auto-increment</strong> --dry-run
SELECT /*!40001 SQL_NO_CACHE */ `id`,`a` FROM `test`.`tt1` FORCE INDEX(`PRIMARY`) WHERE (1=1) ORDER BY `id` LIMIT 1
SELECT /*!40001 SQL_NO_CACHE */ `id`,`a` FROM `test`.`tt1` FORCE INDEX(`PRIMARY`) WHERE (1=1) AND ((`id` > ?)) ORDER BY `id` LIMIT 1
INSERT INTO `test`.`tt2`(`id`,`a`) VALUES (?,?)
# Without --no-safe-auto-increment (default)
[root@centos_2 ~]# pt-archiver --source=h=localhost,D=test,t=tt1 --dest=h=localhost,D=test,t=tt2 --no-delete --where "1=1" --dry-run
SELECT /*!40001 SQL_NO_CACHE */ `id`,`a` FROM `test`.`tt1` FORCE INDEX(`PRIMARY`) WHERE (1=1) <strong>AND (`id` < '5009')</strong> ORDER BY `id` LIMIT 1
SELECT /*!40001 SQL_NO_CACHE */ `id`,`a` FROM `test`.`tt1` FORCE INDEX(`PRIMARY`) WHERE (1=1) <strong>AND (`id` < '5009')</strong> AND ((`id` > ?)) ORDER BY `id` LIMIT 1
INSERT INTO `test`.`tt2`(`id`,`a`) VALUES (?,?)

注意到上面的附加子句 "AND ( id< '5009')" 了嗎?

如果服務器重新啟動,&ndash;no-safe-auto-increment 的這個選項可以防止重新使用 AUTO_INCREMENT 值。請注意,額外的 WHERE 子句包含自歸檔或清除作業開始時自增列的最大值。如果在 pt-archiver 運行時插入新行,pt-archiver 將看不到它們。

好吧,現在我們知道了為什么沒有刪除干凈的“原因”,但為什么呢?AUTO_INCREMENT 的安全問題是什么?

AUTO_INCREMENT 計數器存儲在內存中,當 MySQL 8.0之前的版本 重新啟動(崩潰或其他)時,計數器將重置為最大值。如果發生這種情況并且表正在接受寫入,則 AUTO_INCREMENT 值將更改。

# deleting everything from table
mysql> delete from tt1;
...
mysql> show table status like 'tt1'\G
*************************** 1. row ***************************
           Name: tt1
         Engine: InnoDB
...
 Auto_increment: 10019
...

# Restarting MySQL
[root@centos_2 ~]# systemctl restart mysql

# Verifying auto-increment counter
[root@centos_2 ~]# mysql test -e "show table status like 'tt1'\G"
*************************** 1. row ***************************
           Name: tt1
         Engine: InnoDB
...
 Auto_increment: 1
...

上面的測試結果告訴我們: 這里的問題實際上并不在于 pt-archiver,而在于參數選項。在處理 AUTO_INCREMENT 列時使用 pt-archiver 時,了解使用 &ndash;no-safe-auto-increment 選項很重要。

讓我們用我們的實驗室數據來驗證它。

# Verifying the usage of –no-safe-auto-increment option
[root@centos_2 ~]# pt-archiver --source=h=localhost,D=test,t=tt1 --purge --where "1=1" --no-safe-auto-increment

mysql> select count(*) from test.tt1;
+----------+
| count(*) |
+----------+
|        0 |
+----------+
1 row in set (0.00 sec)

使用 &ndash;no-delete 選項的復制操作也是如此。

[root@centos_2 ~]# pt-archiver --source=h=localhost,D=test,t=tt1 --dest=h=localhost,D=test,t=tt2 --no-delete --where "1=1" --no-safe-auto-increment

mysql> select count(*) from tt1; select count(*) from tt2;
+----------+
| count(*) |
+----------+
|     5009 |
+----------+
1 row in set (0.00 sec)

+----------+
| count(*) |
+----------+
|     5009 |
+----------+
1 row in set (0.00 sec)

通過上面的代碼和實際測試,我們知道了 pt-archiver 的 -[no]safe-auto-increment 選項的原理和作用 。在我們得出一切都很好的結論之前,讓我們多考慮一下選項本身存在的意義。

  • 默認情況下,&ndash;no-delete 操作應包含 &ndash;no-safe-auto-increment 選項。目前,safe-auto-increment 是默認行為。當我們使用 pt-archiver 的 --no-delete 選項時,沒有刪除操作。這意味著 safe-auto-increment 不應成為關注的原因。

  • 對于 MySQL 8.0,不需要 safe-auto-increment 選項。因為 MySQL 8.0 開始,自增的值是持久化的,并且在實例重新啟動或崩潰后自增的最大值不變。

而且由于 MySQL 8.0 auto-increment 是通過重做日志持久化的,這使得它們成為pt-archiver 不關心的一個原因。因此,我們根本不需要 safe-auto-increment 選項。

以上就是“pt-archiver和自增主鍵的問題怎么解決”這篇文章的所有內容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學習更多的知識,請關注億速云行業資訊頻道。

向AI問一下細節

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

AI

朝阳市| 扬州市| 长垣县| 上犹县| 武乡县| 建水县| 弥渡县| 灵宝市| 霍州市| 英德市| 黎城县| 孝感市| 文昌市| 红原县| 清新县| 莒南县| 白朗县| 舞钢市| 米易县| 高州市| 金堂县| 社会| 新巴尔虎左旗| 赤城县| 铅山县| 西吉县| 晋城| 冷水江市| 山阳县| 都兰县| 衡阳市| 离岛区| 江津市| 新干县| 清水河县| 伊通| 谷城县| 平武县| 巴林右旗| 当雄县| 定州市|