數據庫遷移Postgres 到 Mysql 以及優化數據庫

mysql安裝
migration 兼容處理
pg數據導入
sql 兼容處理
mysql | pg 同步
rails mysql 支持

mysql 設置編碼爲utf8mb4(
1.utf8 是 Mysql 中的一種字符集,只支持最長三個字節的 UTF-8字符;
2.要在 Mysql 中保存 4 字節長度的 UTF-8 字符,需要使用 utf8mb4 字符集,但只有 5.5.3 版本以後
3. 對於 CHAR 類型數據,utf8mb4 會多消耗一些空間,根據 Mysql 官方建議,使用 VARCHAR 替代 CHAR
)

設置utf8mb4:

cat /usr/local/etc/my.cnf 

character-set-server=utf8mb4 

mysql.server stop 

mysql.server start 

mysql -uroot -p123456 

show variables like 'character_set_database';

SHOW VARIABLES WHERE Variable_name LIKE 'character_set_%' OR Variable_name LIKE 'collation%';

已有的庫和表更改爲utf8mb4

#更改數據庫編碼:
ALTER DATABASE 數據庫名 CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;

#更改表編碼:
ALTER TABLE 表名CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; 
如有必要,還可以更改列的編碼

MySql錯誤:ERROR 1449 (HY000)

ERROR 1449 (HY000): The user specified as a definer ('mysql.infoschema'@'localhost') does not exist

SET GLOBAL innodb_fast_shutdown = 1;

quit

調用mysql_upgrade升級mysql後,需要重啓mysql才能讓系統表更新生效

mysql_upgrade -u root -p;

重新登錄之後,服務恢復正常。

rails mysql string -> varchar(255);

rails pg string -> varchar
rails pg money -> rails mysql integer

Rails 5 中會用一張ar_internal_metadata表在執行Migration的過程中把要保護的數據庫環境信息存儲到其中,然後在執行高危動作時自動對環境做偵測預判。

db_2ccm_production=# select * from ar_internal_metadata;
     key     |   value    |         created_at         |         updated_at
-------------+------------+----------------------------+----------------------------
 environment | production | 2017-07-13 17:37:26.683599 | 2017-07-13 17:37:26.683599

rails 內置表 ar_internal_metadata 不能同步

50000+的數據使用transaction方式 同步會出現錯誤

[array] partner_order_item: invoice_numbers | refund_invoice_numbers users: exchange_code_array | platforms

mysql 不支持 with_advisory_lock Model.with_advisory_lock('transaction_name', transaction: DB.postgresql?) 事務塊 裏面的 Transaction-level locks

mysql 不支持 reset_pk_sequence 重置序列
pg ActiveRecord::Base.connection.reset_pk_sequence!(table_name) mysql ActiveRecord::Base.connection.execute("ALTER TABLE #{table_name} AUTO_INCREMENT = #{new_max_id};")

mysql 不支持 array 類型的字段
pg add_column table_names, column, :string, array: true, default: [] mysql add_column table_names, column, :text

mysql ALTER TABLE table AUTO_INCREMENT = max_id

TRUNCATE table table_name could drop all table data

mysql 不支持 like serialize columns

OpenSSL::Cipher::AES ruby 2.5.0 出現問題 aes加密 iv截取16位

mysql 不支持 ROW_NUMBER
PG

SELECT
  id
FROM (
  SELECT
      id,
      ROW_NUMBER()
      OVER (PARTITION BY
             start_sale_time
         ORDER BY
             start_sale_time DESC) AS rank
     FROM
         auction_products
     WHERE
         status = #{AuctionProduct.statuses[:presale]}) aps
 WHERE
     aps.rank <= 8
      

MYSQL

      
SELECT
id
FROM(
SELECT
  id,start_sale_time,
  if(@current_timestamp > UNIX_TIMESTAMP(start_sale_time),@rank:=@rank+1,@rank) as the_rank,
  @current_timestamp := UNIX_TIMESTAMP(start_sale_time) as the_time
FROM
  auction_products
WHERE
  status = #{AuctionProduct.statuses[:presale]}
ORDER BY start_sale_time desc
) aps
WHERE
aps.the_rank <= 8
      

mysql 時區設置
show variables like “%time_zone%”;
set global time_zone = ‘+8:00’; ##修改mysql全局時區爲北京時間,即我們所在的東8區
set time_zone = ‘+8:00’; ##修改當前會話時區
flush privileges; #立即生效

mysql extract different with pg

pg extract(‘year’ from time_column) = ?", time.strftime(’%Y’)
mysql extract(year from time_column) = ?", time.strftime(’%Y’)

mysql unsupport pg_search use like or aliyun

用戶首頁: year too big to marshal: 1899 UTC

users.platforms sql更換
update users set users.platforms = case platforms when “” then “—” else concat("—\n- “, REPLACE(REPLACE(REPLACE(REPLACE(users.platforms, “[”,”"), “]”,""), “,”,"\n- "), “’”, “”)) end

索引長度限制 set innodb_large_prefix on

update taggings set taggings.context=“tags”;

sudo apt-get install libmysqlclient-dev

數據格式限制

➜  2ccm-work-api git:(release) rails db:migrate
== 20190410033249 AddRefundIdentification: migrating ==========================
-- add_column(:trade_orders, :refund_identification, :string)
rails aborted!
StandardError: An error has occurred, all later migrations canceled:

Mysql2::Error: Invalid default value for 'created_at': ALTER TABLE `trade_orders` ADD `refund_identification` varchar(255)

解決: mysql> SET GLOBAL sql_mode = '';

PostgresToMysql功能介紹
1、可以將PostgreSQL數據轉換成mysql數據;

2、支持批量轉換;

3、支持命令行操作;

4、支持重複操作;

5、支持在指定的時間自動操作;

6、可以使用SQL命令查詢操作。

MySQL優化
http://www.cnblogs.com/roverliang/p/6481765.html

查看mysql數據庫連接數

show full processlist;

show status;

show status like ‘%下面變量%’;

Aborted_clients 由於客戶沒有正確關閉連接已經死掉,已經放棄的連接數量。 
Aborted_connects 嘗試已經失敗的MySQL服務器的連接的次數。 
Connections 試圖連接MySQL服務器的次數。 
Created_tmp_tables 當執行語句時,已經被創造了的隱含臨時表的數量。 
Delayed_insert_threads 正在使用的延遲插入處理器線程的數量。 
Delayed_writes 用INSERT DELAYED寫入的行數。 
Delayed_errors 用INSERT DELAYED寫入的發生某些錯誤(可能重複鍵值)的行數。 
Flush_commands 執行FLUSH命令的次數。 
Handler_delete 請求從一張表中刪除行的次數。 
Handler_read_first 請求讀入表中第一行的次數。 
Handler_read_key 請求數字基於鍵讀行。 
Handler_read_next 請求讀入基於一個鍵的一行的次數。 
Handler_read_rnd 請求讀入基於一個固定位置的一行的次數。 
Handler_update 請求更新表中一行的次數。 
Handler_write 請求向表中插入一行的次數。 
Key_blocks_used 用於關鍵字緩存的塊的數量。 
Key_read_requests 請求從緩存讀入一個鍵值的次數。 
Key_reads 從磁盤物理讀入一個鍵值的次數。 
Key_write_requests 請求將一個關鍵字塊寫入緩存次數。 
Key_writes 將一個鍵值塊物理寫入磁盤的次數。 
Max_used_connections 同時使用的連接的最大數目。 
Not_flushed_key_blocks 在鍵緩存中已經改變但是還沒被清空到磁盤上的鍵塊。 
Not_flushed_delayed_rows 在INSERT DELAY隊列中等待寫入的行的數量。 
Open_tables 打開表的數量。 
Open_files 打開文件的數量。 
Open_streams 打開流的數量(主要用於日誌記載) 
Opened_tables 已經打開的表的數量。 
Questions 發往服務器的查詢的數量。 
Slow_queries 要花超過long_query_time時間的查詢數量。 
Threads_connected 當前打開的連接的數量。 
Threads_running 不在睡眠的線程數量。 
Uptime 服務器工作了多少秒。

show status like ‘Threads%’;

mysql> show status like 'Threads%';
+-------------------+-------+
| Variable_name     | Value |
+-------------------+-------+
| Threads_cached    | 3204  |
| Threads_connected | 388   |   ###這個數值指的是打開的連接數
| Threads_created   | 6217  |  
| Threads_running   | 6     |  ###這個數值指的是激活的連接數,這個數值一般遠低於connected數值
+-------------------+-------+
4 rows in set (0.01 sec)

查詢數據庫當前設置的最大連接數
show variables like ‘%max_connections%’;

mysql> show variables like '%max_connections%';
+-----------------+-------+
| Variable_name   | Value |
+-----------------+-------+
| max_connections | 5532  |
+-----------------+-------+
1 row in set (0.01 sec)

max_connections 參數可以用於控制數據庫的最大連接數:
show variables like ‘%connect%’;

mysql> show variables like '%connect%';
+-----------------------------------------------+-----------------+
| Variable_name                                 | Value           |
+-----------------------------------------------+-----------------+
| character_set_connection                      | utf8            |
| collation_connection                          | utf8_general_ci |
| connect_timeout                               | 10              |
| disconnect_on_expired_password                | ON              |
| init_connect                                  |                 |
| max_connect_errors                            | 100             |
| max_connections                               | 5532            |
| max_user_connections                          | 5532            |
| performance_schema_session_connect_attrs_size | 0               |
| rds_kill_connections                          | 20              |
| rds_reserved_connections                      | 512             |
| rds_set_connection_id_enabled                 | OFF             |
+-----------------------------------------------+-----------------+
12 rows in set (0.01 sec)

開發人員都會遇見”MySQL: ERROR 1040: Too many connections”的異常情況,
造成這種情況的一種原因是訪問量過高,MySQL服務器抗不住,
這個時候就要考慮增加從服務器分散讀壓力;另一種原因就是MySQL配置文件中max_connections值過小

查看服務器響應的最大連接數:
show global status like ‘Max_used_connections’;

mysql> show global status like 'Max_used_connections';
+----------------------+-------+
| Variable_name        | Value |
+----------------------+-------+
| Max_used_connections | 4669  |
+----------------------+-------+
1 row in set (0.01 sec)

對於mysql服務器最大連接數值的設置範圍比較理想的是:服務器響應的最大連接數值佔服務器上限連接數值的比例值在10%以上,如果在10%以下,說明mysql服務器最大連接上限值設置過高。

修改mysql配置文件my.cnf

MySQL數據庫改名

#!/bin/bash
# 假設將sakila數據庫名改爲new_sakila
# MyISAM直接更改數據庫目錄下的文件即可

mysql -uroot -p123456 -e 'create database if not exists new_db_name'
list_table=$(mysql -uroot -p123456 -Nse "select table_name from information_schema.TABLES where TABLE_SCHEMA='db_name'")

for table in $list_table
do
    mysql -uroot -p123456 -e "rename table db_name.$table to new_db_name.$table"
done

mysql mysqldump導入導出

一、mysqldump導出數據庫

1、導出完整數據:表結構+數據
mysqldump -u用戶名 -p密碼 數據庫名 > 數據庫名.sql

2、導出整個數據庫結構(不包含數據)
增加一個’-d’參數,忽略數據,只導出結構
mysqldump -u用戶名 -p密碼 -d 數據庫名 > 數據庫名.sql

3、導出單個數據表結構和數據
在數據庫名後增加表名
mysqldump -u用戶名 -p密碼 數據庫名 表名 > 數據庫名.sql

4、導出單個數據表結構(不包含數據)
增加一個’-d’參數,忽略數據,只導出結構 並在數據庫名後增加表名
mysqldump -u用戶名 -p密碼 -d 數據庫名 表名 > 數據庫名.sql

5、mysqldump 備份導出數據排除某張表
–ignore-table=dbname.tablename參數
mysqldump -u用戶名 -p密碼 數據庫名 --ignore-table=表名 > 數據庫名.sql

二、 導入數據庫

1、 使用 mysql 命令導入
mysql -u用戶名 -p 數據庫名 < 數據庫名.sql

2、 使用 source 命令導入

create database dbname
use dbname
set names utf8
source /path/數據庫名.sql

Mysql 忘記密碼 重置密碼

//登陸報錯
mysql -uroot -p

root@mendd:/srv/data# mysql -uroot -p
Enter password:
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)

//無密碼啓動MySQL服務
mysqld --console --skip-grant-tables --shared-memory

root@mendd:/srv/data# mysqld_safe --skip-grant-tables --skip-networking
2020-05-26T02:52:53.209750Z mysqld_safe Logging to '/var/log/mysql/error.log'.
2020-05-26T02:52:53.227687Z mysqld_safe Starting mysqld daemon with databases from /var/lib/mysql

//無密碼【登陸】(密碼處直接enter)
mysql -uroot -p

免密碼登陸設置空密碼
//設置【空密碼】
UPDATE mysql.user SET authentication_string='' WHERE user='root' and host='localhost';
flush privileges;

mysql> select host,user,plugin,authentication_string from mysql.user;
+-----------+------------------+-----------------------+------------------------------------------------------------------------+
| host      | user             | plugin                | authentication_string                                                  |
+-----------+------------------+-----------------------+------------------------------------------------------------------------+
| %         | mendd            | mysql_native_password |                                                                        |
| localhost | mysql.infoschema | caching_sha2_password | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED |
| localhost | mysql.session    | caching_sha2_password | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED |
| localhost | mysql.sys        | caching_sha2_password | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED |
| localhost | root             | mysql_native_password |                                                                        |
+-----------+------------------+-----------------------+------------------------------------------------------------------------+
5 rows in set (0.00 sec)

設置加密的密碼
//以caching_sha2_password加密密碼並設置

ALTER user 'root'@'localhost' IDENTIFIED WITH caching_sha2_password BY 'admin';
flush privileges;

mysql> select host,user,plugin,authentication_string from mysql.user;
+-----------+------------------+-----------------------+------------------------------------------------------------------------+
| host      | user             | plugin                | authentication_string                                                  |
+-----------+------------------+-----------------------+------------------------------------------------------------------------+
| %         | mendd            | mysql_native_password |                                                                        |
| localhost | mysql.infoschema | caching_sha2_password | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED |
| localhost | mysql.session    | caching_sha2_password | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED |
| localhost | mysql.sys        | caching_sha2_password | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED |
| localhost | root             | caching_sha2_password | $A$005$%?S!rW	\\gb|_TyswHM/Eb76.9OLnQRrGhQjuN8qlitRfXcT2KKnj02NO7 |
+-----------+------------------+-----------------------+------------------------------------------------------------------------+

//修改加密方式

mysql -uroot -padmin
ALTER user 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'admin';
flush privileges;

mysql> select host,user,plugin,authentication_string from mysql.user;
+-----------+------------------+-----------------------+------------------------------------------------------------------------+
| host      | user             | plugin                | authentication_string                                                  |
+-----------+------------------+-----------------------+------------------------------------------------------------------------+
| %         | mendd            | mysql_native_password |                                                                        |
| localhost | mysql.infoschema | caching_sha2_password | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED |
| localhost | mysql.session    | caching_sha2_password | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED |
| localhost | mysql.sys        | caching_sha2_password | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED |
| localhost | root             | mysql_native_password | *4ACFE3202A5FF5CF467898FC58AAB1D615029441                              |
+-----------+------------------+-----------------------+------------------------------------------------------------------------+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章