数据库迁移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                              |
+-----------+------------------+-----------------------+------------------------------------------------------------------------+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章