複製表的方法

2022-01-09 20:31:50 字數 4141 閱讀 3799

一、將資料匯出為 sql 檔案。

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

將資料匯出為 sql 檔案儲存。上面幾個引數的含義分別是:

1、–single-transaction 的作用是,在匯出資料的時候不需要對錶 db1.t 加表鎖,而是使用 start transaction with consistent snapshot 的方法;

2、–add-locks 設定為 0,表示在輸出的檔案結果裡,不增加" lock tables t write;" ;

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

4、–set-gtid-purged=off 表示的是,不輸出跟 gtid 相關的資訊;

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

二、執行檔案,新增到表中

mysql -h127.0.0.1

-p13000 -uroot db2 -e "source /client_tmp/t.sql"

source 並不是一條 sql 語句,而是乙個客戶端命令。也就是伺服器端具體執行的是檔案中的一條條 sql 語句,所以binlog 記錄的都是具體的 sql。1、生成的 sql 檔案儲存在客戶端2、預設儲存資料方式是多個記錄對,如下面格式

如果想要儲存為一條語句只儲存一條記錄,那麼可以加上引數–skip-extended-insert。

一、匯出為 csv 檔案

select

*from db1.t where a>

900into outfile '

/server_tmp/t.csv

';

注意:1、into outfile 指定了檔案的生成位置(/server_tmp/),這個位置必須受引數 secure_file_priv 的限制。

引數 secure_file_priv 的可選值和作用分別是:

1)如果設定為 empty,表示不限制檔案生成的位置,這是不安全的設定;

2)如果設定為乙個表示路徑的字串,就要求生成的檔案只能放在這個指定的目錄,或者它的子目錄;

3)如果設定為 null,就表示禁止在這個 mysql 例項上執行 select … into outfile 操作。

2、如果同乙個目錄下存在同名檔案,就會報錯

3、一般情況下一條記錄就對應 csv 檔案中的一行,但是如果某個字段值中有 "換行、製表符" 那麼檔案中也會包含,並且使用 "\" 來轉義。

二、匯入資料

load data infile '

/server_tmp/t.csv

'into

table db2.t;

過程:1、開啟檔案 /server_tmp/t.csv,以製表符 (\t) 作為欄位間的分隔符,以換行符(\n)作為記錄之間的分隔符,進行資料讀取;

2、啟動事務。

3、判斷每一行的字段數與表 db2.t 是否相同:

1)若不相同,則直接報錯,事務回滾;

2)若相同,則構造成一行,呼叫 innodb 引擎介面,寫入到表中。

4、重複步驟 3,直到 /server_tmp/t.csv 整個檔案讀入完成,提交事務。

1、檔案儲存在伺服器端

2、關於 binlog 的記錄,過程如下:

1)主庫執行完成後,將 /server_tmp/t.csv 檔案的內容直接寫到 binlog 檔案中。

2)往binlog

檔案中寫入語句load data local infile 『/tmp/sql_load_mb-1-0』 into table `db2`.`t`。

3)把這個 binlog 日誌傳到備庫。

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

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

關於 "local":

1)不加「local」,是讀取服務端的檔案,這個檔案必須在 secure_file_priv 指定的目錄或子目錄下;

2)加上「local」,讀取的是客戶端的檔案,只要 mysql 客戶端有訪問這個檔案的許可權即可。這時候,mysql 客戶端會先把本地檔案傳給服務端(其他會話涉及的操作),然後執行上述的 load data 流程。

3、上面的匯出操作並不會匯出表結構,所以,如果嚮導出表結構,可以使用 mysqldump 來同時匯出 csv 和表結構

mysqldump -h$host -p$port -u$user

--single-transaction --set-gtid-purged=off db1 t --where="a>900" --tab=$secure_file_priv

會在$secure_file_priv 定義的目錄下,建立乙個 t.sql 檔案儲存建表語句,同時建立乙個 t.txt 檔案儲存 csv 資料。

在5.6之前,想要直接把.frm和.ibd檔案拷貝到要拷貝的目錄下是不行的,因為乙個innodb表除了需要這兩個檔案還需要在資料字典中註冊。但是從 5.6 開始可以解決這一問題,在 5.6 引入了可傳輸空間,可以通過匯出 + 匯入表空間來實現拷貝

假設我們現在的目標是在 db1 庫下,複製乙個跟表 t 相同的表 r,具體的執行步驟如下:

1、執行 create table r like t,建立乙個相同表結構的空表;

2、執行 alter table r discard tablespace,這時候 r.ibd 檔案會被刪除;

3、執行 flush table t for export,這時候 db1 目錄下會生成乙個 t.cfg 檔案;

4、在 db1 目錄下執行 cp t.cfg r.cfg; cp t.ibd r.ibd;這兩個命令(這裡需要注意的是,拷貝得到的兩個檔案,mysql 程序要有讀寫許可權);

5、執行 unlock tables,這時候 t.cfg 檔案會被刪除;

6、執行 alter table r import tablespace,將這個 r.ibd 檔案作為表 r 的新的表空間,由於這個檔案的資料內容和 t.ibd 是相同的,所以表 r 中就有了和表 t 相同的資料。

注意:

1、在第 3 步執行完 flsuh table 命令之後,db1.t 整個表處於唯讀狀態,直到執行 unlock tables 命令後才釋放讀鎖;

2、在執行 import tablespace 的時候,為了讓檔案裡的表空間 id 和資料字典中的一致,會修改 r.ibd 的表空間 id。而這個表空間 id 存在於每乙個資料頁中。因此,如果是乙個很大的檔案(比如 tb 級別),每個資料頁都需要修改,所以你會看到這個 import 語句的執行是需要一些時間的。當然,如果是相比於邏輯匯入的方法,import 語句的耗時是非常短的。

1、必須是全表拷貝,不能條件拷貝

2、需要到伺服器上拷貝資料,在使用者無法登入資料庫主機的場景下無法使用

3、由於是通過拷貝物理檔案實現的,源表和目標表都是使用 innodb 引擎時才能使用

1、前兩個都是邏輯備份,也就是可以跨引擎使用,最後乙個不行

2、前兩個可以條件拷貝,最後乙個不行

3、第二個功能是最靈活的,但是在集群從庫接收時會比較耗時(需要先拷貝 csv 檔案資料到本地臨時檔案),最後乙個執行效率是最高的,但是不能跨引擎,且只能進行全量拷貝。

mysql複製表的方法

1.使用like,只複製表結構到新錶 create table targettable like sourcetable 2.複製表結構及資料到新錶 insert into targettable select from sourcetable 3.可以拷貝乙個表中其中的一些字段 create ta...

MySQL命令複製表的方法

mysql中用命令列複製表結構的方法主要有以下幾種 1.只複製表結構到新錶 create table 新錶 select from 舊表 where 1 2 或 create table 新錶 like 舊表 注意上面兩種方式,前一種方式是不會複製時的主鍵型別和自增方式是不會複製過去的,而後一種方式...

SQL語句複製表的方法

t sql語句複製表的方法 我在sql server 2000中有現個資料庫datahr及demo,它們的結構是一樣,其它有乙個表名為 gbitem.現在我想將demo資料庫的表名 gbitem的全部內容複製到datahr資料庫的表名為 gbitem中。請問此t sql語句應該怎麼寫?謝謝高人指點!...