日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

mysql 复制表耗时_聊一下mysql的表复制

發布時間:2024/8/5 数据库 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mysql 复制表耗时_聊一下mysql的表复制 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1 insert...from的問題

insert … select 是很常見的在兩個表之間拷貝數據的方法。需要注意,在可重復讀隔離級別下,這個語句會給

select的表里掃描到的記錄和間隙加讀鎖。

以下對insert...select 進行一下測試

全表讀或主鍵排序讀

sessionA

mysql> insert into trajectory_min_section_0511_copy select * from trajectory_min_section_0511;

sessionB

mysql> show engine innodb status;

1451 lock struct(s), heap size 155856, 121231 row lock(s), undo log entries 119783

mysql> show engine innodb status;

3088 lock struct(s), heap size 303312, 258340 row lock(s), undo log entries 255254

mysql> show engine innodb status;

15004 lock struct(s), heap size 1466576, 1256305 row lock(s), undo log entries 1241304

終止sessionA后

sessionB

mysql> show engine innodb status;

ROLLING BACK 23737 lock struct(s), heap size 2302160, 1987628 row lock(s), undo log entries 471818

mysql> show engine innodb status;

ROLLING BACK 23737 lock struct(s), heap size 2302160, 1987628 row lock(s), undo log entries 20019

通過測試可以看到row locks是一個慢慢增長的過程。undo log entries也在一直增長,這個的作用是為了rollback恢復。

用主鍵升序插入以及用主鍵降序插入:

select * from trajectory_min_section_0511 order id(PK) ASC

select * from trajectory_min_section_0511 order id(PK) DESC

也是一樣的效果,感興趣的可以測試一下。

從上面測試可知:通過主鍵排序或則不加排序字段的導入操作"insert into A select * from B",是會鎖B表,但他的鎖是逐步地鎖定已經掃描過的記錄。

當終止后可以看到undo log entries數量慢慢降下去

非主鍵排序讀

sessionA

mysql> insert into trajectory_min_section_0511_copy select * from trajectory_min_section_0511 order by t_distance desc;

sessionB

sessionA執行過程中執行n次

mysql> show engine innodb status;

63595 lock struct(s), heap size 6168784, 5325513 row lock(s), undo log entries 5118624

從上面測試可知:非主鍵排序的導入操作,是會鎖表,而且糟糕的是,鎖是一開始就會鎖定整張表。

讀寫驗證

sessionA

mysql> insert into trajectory_min_section_0511_copy select * from trajectory_min_section_0511;

sessionB

mysql> select * from trajectory_min_section_0511 where id=1715

搜索靠前主鍵數據可以正常返回

mysql> update trajectory_min_section_0511 set direction=2 where id=1715

更新靠前主鍵數據超時無法返回

sessionA

mysql> insert into trajectory_min_section_0511_copy select * from trajectory_min_section_0511 order by id desc;

sessionB

mysql> select * from trajectory_min_section_0511 where id=9999

搜索靠后主鍵數據可以正常返回

mysql> update trajectory_min_section_0511 set direction=2 where id=1715

更新靠后主鍵數據超時無法返回

以上測試在上鎖過程中,不能dml操作任何被上鎖的行,直到鎖釋放。

如果已知對源表的掃描行數和加鎖范圍很小的話,簡單地使用insert … select 語句即可實現。如果對線上重點表遷移,為了避免對源表加讀鎖,更穩妥

的方案是先將數據寫到外部文本文件,然后再寫回目標表。

2 高效加載數據

提高寫入、加載速度的幾個原則,這些原則在任何數據庫上都是通用的:

把數據從緩存刷新到磁盤次數越少,數據加載的越快。因此,批量加載一定是比單條加載效率更高,因為批量插入的行可以先行緩存,然后在

加載操作時候一次性刷到磁盤上,減少磁盤的隨機讀操作。

表的索引越少,加載速度越快,如果表有多個列存在索引,每次插入都需要更新所有索引完后才會識別到新的行加入。所以不要建無謂的索引。

短sql比長sql加載速度更快,因為在服務器上解析操作耗時更少,并且可以更快的通過網絡發送到服務器。

加載數據一般有insert和load兩種,接下來詳細解讀一下底層實現的不同。

2.1 load主備同步流程

主庫執行完成后,將/root/table.txt文件的內容直接寫到一個外部文件中。

往binlog文件中寫入語句load data local infile ‘/tmp/SQL_LOAD_MB-1-0’ INTO TABLE db2.t。

讀取本地文件

把這個binlog日志傳到備庫。

備庫的apply線程在執行這個事務日志時:

先將binlog中t.csv文件的內容讀出來,寫入到本地臨時目錄/tmp/SQL_LOAD_MB-1-0 中;

再執行load data語句,往備庫的db2.t表中插入跟主庫相同的數據。

147d3f6f.png

2.2 總結

總的來說,根據官方介紹load可以快出insert 20多倍

load 的底層實現的優化:

1 跳過sql解析,直接生成數據文件;

2 在導入之前會關掉索引,導入完成后更新索引;而與之對比的Insert的處理機制是:每插入一條則更新一次數據庫,更新一次索引。

官網的一些解答

f01fa40b.png

4 數據拷貝方法

介紹三種mysql數據拷貝的主流方法,分別是mysqldump(sql語句拷貝)、load(csv文件拷貝)、以及物理文件拷貝。

4.1 mysql dump

mysqldump -h$host -P$port -u$user --add-locks=0 --no-create-info --single-transaction --set-gtid-purged=OFF db1 t --where="a>900" --result-file=/client_tmp/t.sql

主要參數含義如下:

–single-transaction的作用是,在導出數據的時候不需要對表db1.t加表鎖,而是使用START TRANSACTION WITH CONSISTENT SNAPSHOT的方法;

–add-locks設置為0,表示在輸出的文件結果里,不增加" LOCK TABLES t WRITE;" ;

–no-create-info的意思是,不需要導出表結構;

–set-gtid-purged=off表示的是,不輸出跟GTID相關的信息;

–result-file指定了輸出文件的路徑,其中client表示生成的文件是在客戶端機器上的。

通過這條mysqldump命令生成的t.sql文件中就包含了如圖1所示的INSERT語句。

ae0f129a.png

可以看到一個insert中包含多個value對,這樣插入執行速度可以加快。

這也是navicat 上 data transfer功能

148c3bcb.png

4.2 load

show variables like ‘%secure_file_priv%’;

如果設置為empty,表示不限制文件生成的位置,這是不安全的設置;

如果設置為一個表示路徑的字符串,就要求生成的文件只能放在這個指定的目錄,或者它的子目錄;

如果設置為NULL,就表示禁止在這個MySQL實例上執行select … into outfile 操作。

通過修改配置文件永久生效

4f4991f4.png

設置后可以通過命令導出

select * from db1.t where a>900 into outfile '/server_tmp/t.csv';

導出的csv文件可以用如下命令導入

load data infile '/server_tmp/t.csv' into table db2.t;

拷貝到數據庫本地后,可以用本地導入,比遠程導入更快,因為省去了在load這個事務中網絡傳輸,減輕數據庫壓力。

load data local infile '/server_tmp/t.csv' into table db2.t;

4.3 物理拷貝

在掌握了邏輯拷貝的方法后,是否有物理導數據的方法呢?比如,直接把db1.t表的.frm文件和.ibd文件拷貝到db2目錄下,是否可行呢?

答案是不行的。

因為,一個InnoDB表,除了包含這兩個物理文件外,還需要在數據字典中注冊。直接拷貝這兩個文件的話,因為數據字典中沒有db2.t這個表,系統是不會識別和接受它們的。

不過,在MySQL 5.6版本引入了可傳輸表空間(transportable tablespace)的方法,可以通過導出+導入表空間的方式,實現物理拷貝表的功能。

假設我們現在的目標是在db1庫下,復制一個跟表trajectory_min_section_0511相同的表trajectory_min_section_0511_copy,具體的執行步驟如下:

-- 源端執行

flush table trajectory_min_section_0511 for export

這時候數據庫目錄下會生成一個trajectory_min_section_0511.cfg文件;

cp trajectory_min_section_0511.ibd trajectory_min_section_0511_copy.ibd;

在db1目錄下執行cp trajectory_min_section_0511.cfg trajectory_min_section_0511_copy.cfg; 這兩個命令(

這里需要注意的是,拷貝得到的兩個文件,MySQL進程要有讀寫權限);

unlock tables

trajectory_min_section_0511.cfg文件會被刪除;

-- 目標端執行

create table trajectory_min_section_0511_copy like trajectory_min_section_0511;

首先創建一個相同表結構的空表

alter table trajectory_min_section_0511_copy discard tablespace;

這時候trajectory_min_section_0511_copy.ibd文件會被刪除

alter table trajectory_min_section_0511_copy import tablespace

將這個trajectory_min_section_0511_copy.ibd文件作為表trajectory_min_section_0511_copy的新的表空間,

由于這個文件的數據內容和trajectory_min_section_0511.ibd是相同的,所以表trajectory_min_section_0511_copy中

就有了和表trajectory_min_section_0511相同的數據。

測試后最后一步導入500w耗時10s左右,其他操作都是立刻執行

7c9e2e74.png

幾點注意:

在第3步執行完flush table命令之后,整個表trajectory_min_section_0511處于只讀狀態,直到執行unlock tables命令后才釋放讀鎖;

在執行import tablespace的時候,為了讓文件里的表空間id和數據字典中的一致,會修改trajectory_min_section_0511_copy.ibd的表空間id。

而這個表空間id存在于每一個數據頁中。因此,如果是一個很大的文件(比如TB級別),每個數據頁都需要修改,import語句的執行是需要一些時間的。

當然,如果是相比于邏輯導入的方法,import語句的耗時是非常短的。

4.4 三種方式對比

對比一下這三種方法的優缺點。

物理拷貝的方式速度最快,尤其對于大表拷貝來說是最快的方法。如果出現誤刪表的情況,用備份恢復出誤刪之前的臨時庫,然后再把臨時庫中的表拷貝到生產庫上,是恢復數據最快的方法。但是,這種方法的使用也有一定的局限性:

a) 必須是全表拷貝,不能只拷貝部分數據;

b) 需要到服務器上拷貝數據,在用戶無法登錄數據庫主機的場景下無法使用;

c) 由于是通過拷貝物理文件實現的,源表和目標表都是使用InnoDB引擎時才能使用。

用mysqldump生成包含INSERT語句文件的方法,可以在where參數增加過濾條件,來實現只導出部分數據。這個方式的不足之一是,不能使用join這種比較復雜的where條件寫法。

用select … into outfile的方法是最靈活的,支持所有的SQL寫法。但,這個方法的缺點之一就是,每次只能導出一張表的數據,而且表結構也需要另外的語句單獨備份。

后兩種方式都是邏輯備份方式,是可以跨引擎使用的。

5 當數據量很大時

拋開最后一種物理拷貝,因為在線上時不一定可以登錄數據庫主機,而且也可能只拷貝部分數據。那一般就是使用load data infile方式導入。

當數據量極大(10+G,千萬級別)時,用之前介紹的方式會有很大問題。

load為一個長事務,最后commit后才插入數據庫。

undo增長快速,無法回收。數據庫性能下降,undo大小大于buffer pool,就會開始內存和磁盤的交換。

可以大文件拆小,監控cpu后,在合理的利用率情況下,多線程load。

6 擴展知識點

針對并發場景的一致性問題,第一個能想到的是加鎖,但是數據庫中所有操作都上鎖勢必會帶來性能的低下,mysql的隔離級別(isolation level)最高級叫串行化,

其設計上可以認為就是加一把大鎖,讀的時候加共享鎖,不能寫,寫的時候,加的是排它鎖,阻塞其它事務的寫入和讀取,若是其它的事務長時間不能寫入就會直接報超時,所以它的性能也是最差的,對于它來就沒有什么并發性可言。

在InnoDB 的讀提交和可重復讀兩種級別都使用了多版本并發控制模型(MVCC)

比如在實現可重復讀的隔離級別,只需要在事務開始的時候創建一致性視圖,也叫做快照,之后的查詢里都共用這個一致性視圖,后續的事務對數據的更改

是對當前事務是不可見的,這樣就實現了可重復讀。 中每一個事務都有一個自己的事務id,并且是唯一的,遞增的 。

71a299d8.png

最開始數據的版本是V0;

T1時刻發起了一個寫任務,這是把數據clone了一份,進行修改,版本變為V1,但任務還未完成;

T2時刻并發了一個讀任務,依然可以讀V0版本的數據;

T3時刻又并發了一個讀任務,依然不會阻塞;

對于Mysql中的每一個數據行都有可能存在多個版本,在每次事務更新數據的時候,都會生成一個新的數據版本,并且把自己的數據id賦值給當前版本的row trx_id。

e6536994.png

如圖中所示,假如三個事務更新了同一行數據,那么就會有對應的三個數據版本。

實際上版本1、版本2并非實際物理存在的,而圖中的U1和U2實際就是undo log,這v1和v2版本是根據當前v3和undo log計算出來的。

當出現事務回滾的時候,通過undo log反向重現redo log的過程,就可以將當前數據回退回事務開始前數據狀態。

當事務提交后undo塊就會慢慢的回收。要避免長事務,因為如果長事務中有更新,就意味著占用著行鎖,導致別的語句更新被鎖。還有讀的事務會導致undo log不能回收,導致回滾段空間膨脹。

擴展閱讀 萬字長文,幫你梳理存儲引擎之Heap表關鍵知識點

總結

以上是生活随笔為你收集整理的mysql 复制表耗时_聊一下mysql的表复制的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 欧美黑人猛交 | 国产视频一区在线播放 | 波多野结衣二区三区 | 国产成人精品亚洲精品色欲 | 国产精品亚洲综合 | 黑人巨大猛交丰满少妇 | 午夜dv内射一区二区 | 免费网站观看www在线观看 | 国产成人自拍在线 | 奇米影视狠狠 | 抱着老师的嫩臀猛然挺进视频 | 国产精品美女久久久网av | 欧洲精品久久一区二区 | 中文字幕在线观看视频www | 久久国产精品免费视频 | 免费网站观看www在线观看 | 男人天堂一区 | 久久影业 | babes性欧美69 | 国产无套视频 | 亚洲第五页 | 99视屏 | 夜夜看av| 欧美三级黄 | 91成人免费在线观看视频 | 亚洲国产一区二区a毛片 | 成人精品一区二区 | 丁香婷婷色 | 蜜桃视频在线观看一区二区 | se日韩 | 免费毛片视频 | 国产欧美在线看 | 亚洲美女一区二区三区 | 日韩日b视频 | 毛片xxx| 欧美日韩黄色网 | 18视频在线观看男男 | 一区二区三区在线免费观看视频 | 国内性视频 | 都市激情第一页 | 337p日本大胆噜噜噜噜 | 亚洲天堂男人的天堂 | 五月天堂婷婷 | 精品国产乱码久久久久久蜜柚 | 麻豆黄色网 | 欧美性色网 | 日韩欧美国产综合 | 欧美成人免费播放 | 国产午夜精品久久久久久久 | 亚洲精品国产精品国 | 亚洲色图10p | 成人av久久| 午夜视| www.涩涩爱 | 爱色av网站 | 男女扒开双腿猛进入爽爽免费 | 狠狠狠狠狠 | 葵司免费一区二区三区四区五区 | 申鹤乳液狂飙 | 欧洲人妻丰满av无码久久不卡 | 青青草福利 | 亚洲精品影视 | 又骚又黄的视频 | 国产欧美一区二区三区鸳鸯浴 | 欧美亚洲综合久久 | 区一区二视频 | 国产亚洲一区二区三区不卡 | 在线手机av | 欧美 日韩 国产一区 | 一区二区激情 | 欧美人妖另类 | 亚洲九九爱 | 爱爱爱免费视频 | 亚洲欧美国产精品久久久久久久 | 爱啪啪网站| 亚洲精品一区二区口爆 | 欧美综合日韩 | 久久精品黄色 | 国产资源在线视频 | 黄色大片免费网站 | 碰在线视频 | 成年人理论片 | 东方影库av| 久久久精品影院 | 亚洲天堂2015| 视频在线观看一区二区三区 | 婷婷深爱网 | 国产 日韩 欧美 综合 | 亚洲国产一区二区a毛片 | 国产肉体ⅹxxx137大胆 | 比利时xxxx性hd极品 | 性欧美视频在线观看 | 成人午夜在线 | 中国一及毛片 | 天天想你在线观看完整版电影免费 | 久久久性色精品国产免费观看 | 日韩亚洲视频 | 亚洲一区二区三区在线免费观看 | 欧美激情一二三区 |