MySQL刪除數據表前三個月數據


testrecord數據庫中存儲着玩家行為記錄,每三個月需要清理掉。

刪除數據前的准備

查看testrecord數據庫的大小:

MySQL [(none)]> USE information_schema;
Database changed
MySQL [information_schema]> SELECT CONCAT(ROUND(SUM(DATA_LENGTH/1024/1024/1024),2),'GB')
    -> as DATA FROM TABLES WHERE
    -> table_schema='testrecord';
+---------+
| DATA    |
+---------+
| 56.70GB |
+---------+
1 row in set (0.00 sec)

查看testrecord數據庫各數據表大小:

MySQL [information_schema]> SELECT
    -> table_schema as '數據庫',
    -> table_name as '表名',
    -> table_rows as '記錄數',
    -> TRUNCATE(data_length/1024/1024/1024, 2) as '數據容量(GB)',
    -> TRUNCATE(index_length/1024/1024/1024, 2) as '索引容量(GB)'
    -> FROM information_schema.tables
    -> WHERE table_schema='testrecord'
    -> ORDER BY data_length DESC, index_length DESC;
+----------- +-------------------+-----------+----------------+----------------+
| 數據庫     | 表名               | 記錄數    | 數據容量(GB)    | 索引容量(GB)   |
+----------- +-------------------+----------------------------+----------------+
| testrecord | playeritem        |  71206129 |           9.71 |           4.17 |
| testrecord | dropcord          | 102342337 |           7.92 |           6.22 |
| testrecord | ipcord            |  22256444 |           4.97 |           3.93 |
| testrecord | store             |  16583137 |           2.58 |           1.20 |
| testrecord | teip              |   6887136 |           2.43 |           1.28 |

以上得知:
需要清理數據的前三個數據表分別是:playeritem、dropcord、ipcord

查看創建數據表的SQL語句:

MySQL [(none)]> USE testrecord;
Database changed
MySQL [testrecord]> SHOW CREATE TABLE playeritem \G
*************************** 1. row ***************************
       Table: playeritem
Create Table: CREATE TABLE `playeritem` (
#——————————————————字段結構略————————————————————————#
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT
/*!50100 PARTITION BY RANGE (`cordTime`)
(PARTITION `playeritem_2021-05` VALUES LESS THAN (1622476800) ENGINE = InnoDB,
 PARTITION `playeritem_2021-06` VALUES LESS THAN (1625068800) ENGINE = InnoDB,
 PARTITION `playeritem_2021-07` VALUES LESS THAN (1627747200) ENGINE = InnoDB,
 PARTITION `playeritem_2021-08` VALUES LESS THAN (1630425600) ENGINE = InnoDB,
 PARTITION `playeritem_2021-09` VALUES LESS THAN (1633017600) ENGINE = InnoDB,
 PARTITION `playeritem_2021-10` VALUES LESS THAN (1635696000) ENGINE = InnoDB,
 PARTITION `playeritem_2021-11` VALUES LESS THAN (1638288000) ENGINE = InnoDB,
 PARTITION `playeritem_2021-12` VALUES LESS THAN (1640966400) ENGINE = InnoDB,
 PARTITION playeritem_max VALUES LESS THAN MAXVALUE ENGINE = InnoDB) */
1 row in set (0.00 sec)

MySQL [testrecord]> SHOW CREATE TABLE dropcord \G
*************************** 1. row ***************************
       Table: dropcord
Create Table: CREATE TABLE `dropcord` (
#——————————————————字段結構略————————————————————————#
) ENGINE=InnoDB DEFAULT CHARSET=utf8
/*!50100 PARTITION BY RANGE (to_days(cordtime))
(PARTITION p202105 VALUES LESS THAN (738307) ENGINE = InnoDB,
 PARTITION p202106 VALUES LESS THAN (738337) ENGINE = InnoDB,
 PARTITION p202107 VALUES LESS THAN (738368) ENGINE = InnoDB,
 PARTITION p202108 VALUES LESS THAN (738399) ENGINE = InnoDB,
 PARTITION p202109 VALUES LESS THAN (738429) ENGINE = InnoDB,
 PARTITION p202110 VALUES LESS THAN (738460) ENGINE = InnoDB,
 PARTITION p202111 VALUES LESS THAN (738490) ENGINE = InnoDB,
 PARTITION p202112 VALUES LESS THAN (738521) ENGINE = InnoDB,
 PARTITION pmax VALUES LESS THAN MAXVALUE ENGINE = InnoDB) */
1 row in set (0.00 sec)

MySQL [testrecord]> SHOW CREATE TABLE ipcord \G
*************************** 1. row ***************************
       Table: ipcord
Create Table: CREATE TABLE `ipcord` (
#——————————————————字段結構略————————————————————————#
) ENGINE=InnoDB DEFAULT CHARSET=utf8
/*!50100 PARTITION BY RANGE (to_days(cordtime))
(PARTITION p202105 VALUES LESS THAN (738307) ENGINE = InnoDB,
 PARTITION p202106 VALUES LESS THAN (738337) ENGINE = InnoDB,
 PARTITION p202107 VALUES LESS THAN (738368) ENGINE = InnoDB,
 PARTITION p202108 VALUES LESS THAN (738399) ENGINE = InnoDB,
 PARTITION p202109 VALUES LESS THAN (738429) ENGINE = InnoDB,
 PARTITION p202110 VALUES LESS THAN (738460) ENGINE = InnoDB,
 PARTITION p202111 VALUES LESS THAN (738490) ENGINE = InnoDB,
 PARTITION p202112 VALUES LESS THAN (738521) ENGINE = InnoDB,
 PARTITION pmax VALUES LESS THAN MAXVALUE ENGINE = InnoDB) */
1 row in set (0.00 sec)

以上得知:
數據表采用了RNAGE分區,分別以月份天數創建了分區

查看數據表分區情況

MySQL [testrecord]> SELECT PARTITION_NAME part,
    -> PARTITION_EXPRESSION expr,
    -> PARTITION_DESCRIPTION descr,
    -> TABLE_ROWS
    -> FROM information_schema.PARTITIONS
    -> WHERE TABLE_SCHEMA = schema() AND TABLE_NAME = 'playeritem';
+--------------------+------------+------------+------------+
| part               | expr       | descr      | TABLE_ROWS |
+--------------------+------------+------------+------------+
| playeritem_2021-05 | `cordTime` | 1622476800 |   96549342 |
| playeritem_2021-06 | `cordTime` | 1625068800 |   26259322 |
| playeritem_2021-07 | `cordTime` | 1627747200 |   44541353 |
| playeritem_2021-08 | `cordTime` | 1630425600 |   27246100 |
| playeritem_2021-09 | `cordTime` | 1633017600 |   29226451 |
| playeritem_2021-10 | `cordTime` | 1635696000 |    6806093 |
| playeritem_2021-11 | `cordTime` | 1638288000 |          0 |
| playeritem_2021-12 | `cordTime` | 1640966400 |          0 |
| playeritem_max     | `cordTime` | MAXVALUE   |          0 |
+------------------------+-------------------+------------+------------+
9 rows in set (0.00 sec)

MySQL [testrecord]> SELECT PARTITION_NAME part,
    -> PARTITION_EXPRESSION expr,
    -> PARTITION_DESCRIPTION descr,
    -> TABLE_ROWS
    -> FROM information_schema.PARTITIONS
    -> WHERE TABLE_SCHEMA = schema() AND TABLE_NAME = 'dropcord';
+---------+-------------------+----------+------------+
| part    | expr              | descr    | TABLE_ROWS |
+---------+-------------------+----------+------------+
| p202105 | to_days(cordtime) | 738307   |   60519201 |
| p202106 | to_days(cordtime) | 738337   |   30759304 |
| p202107 | to_days(cordtime) | 738368   |   55525655 |
| p202108 | to_days(cordtime) | 738399   |   51800453 |
| p202109 | to_days(cordtime) | 738429   |   58897747 |
| p202110 | to_days(cordtime) | 738460   |   14470693 |
| p202111 | to_days(cordtime) | 738490   |          0 |
| p202112 | to_days(cordtime) | 738521   |          0 |
| pmax    | to_days(cordtime) | MAXVALUE |          0 |
+---------+---------------------+----------+------------+
9 rows in set (0.00 sec)

MySQL [testrecord]> SELECT PARTITION_NAME part,
    -> PARTITION_EXPRESSION expr,
    -> PARTITION_DESCRIPTION descr,
    -> TABLE_ROWS
    -> FROM information_schema.PARTITIONS
    -> WHERE TABLE_SCHEMA = schema() AND TABLE_NAME = 'ipcord';
+---------+---------------------+----------+------------+
| part    | expr                | descr    | TABLE_ROWS |
+---------+---------------------+----------+------------+
| p202105 | to_days(cordtime) | 738307   |   70512202 |
| p202106 | to_days(cordtime) | 738337   |   50759503 |
| p202107 | to_days(cordtime) | 738368   |   65529654 |
| p202108 | to_days(cordtime) | 738399   |   11692729 |
| p202109 | to_days(cordtime) | 738429   |   17989204 |
| p202110 | to_days(cordtime) | 738460   |    5010364 |
| p202111 | to_days(cordtime) | 738490   |          0 |
| p202112 | to_days(cordtime) | 738521   |          0 |
| pmax    | to_days(cordtime) | MAXVALUE |          0 |
+---------+---------------------+----------+------------+
9 rows in set (0.00 sec)

刪除數據
依次刪除5、6、7月的數據

ALTER TABLE playeritem DROP PARTITION playeritem_2021-05;
ALTER TABLE dropcord DROP PARTITION p202105;
ALTER TABLE ipcord DROP PARTITION p202105;

刪除數據后的檢查
依次檢查分區表情況

MySQL [testrecord]> SELECT PARTITION_NAME part,
    -> PARTITION_EXPRESSION expr,
    -> PARTITION_DESCRIPTION descr,
    -> TABLE_ROWS
    -> FROM information_schema.PARTITIONS
    -> WHERE TABLE_SCHEMA = schema() AND TABLE_NAME = 'dropcord';
+---------+---------------------+----------+------------+
| part    | expr                | descr    | TABLE_ROWS |
+---------+---------------------+----------+------------+
| p202108 | to_days(recordtime) | 738399   |   51800453 |
| p202109 | to_days(recordtime) | 738429   |   58897747 |
| p202110 | to_days(recordtime) | 738460   |   14496732 |
| p202111 | to_days(recordtime) | 738490   |          0 |
| p202112 | to_days(recordtime) | 738521   |          0 |
| pmax    | to_days(recordtime) | MAXVALUE |          0 |
+---------+---------------------+----------+------------+
6 rows in set (0.00 sec)

並再次檢查數據表大小確認存儲空間是否已釋放。

將以上操作寫入腳本
clear_table_partition.sh

#!/bin/sh

source /root/.bash_profile

for db in $(mysql_cmd -Ne "SHOW DATABASES;" | grep testrecord)
do

    # look the table partitions
    l_t_cmd="SELECT PARTITION_NAME part, \
             PARTITION_EXPRESSION expr, \
             PARTITION_DESCRIPTION descr, \
             TABLE_ROWS \
             FROM information_schema.PARTITIONS \
             WHERE \
             TABLE_SCHEMA = schema() \
             AND TABLE_NAME = 'ipcord';"
    echo $l_t_cmd
    echo $db
    mysql_cmd -e "USE $db; $l_t_cmd;"

    # drop the table partitions
    d_t_cmd="ALTER TABLE playeritem DROP PARTITION playeritem_2021-05;
             ALTER TABLE playeritem DROP PARTITION playeritem_2021-06;
             ALTER TABLE playeritem DROP PARTITION playeritem_2021-07;
             ALTER TABLE dropcord DROP PARTITION p202105;
             ALTER TABLE dropcord DROP PARTITION p202106;
             ALTER TABLE dropcord DROP PARTITION p202107;
             ALTER TABLE ipcord DROP PARTITION p202105;
             ALTER TABLE ipcord DROP PARTITION p202106;
             ALTER TABLE ipcord DROP PARTITION p202107;"
    echo $d_t_cmd
    echo $db
    mysql_cmd -e "USE $db; $d_t_cmd;"

done

總結
1、source命令可在當前shell環境中讀取並執行來自文件里的命令

2、環境變量文件.bash_profile對當前登錄用戶有效,在文件內設置登錄MySQL別名,簡化代碼:
在這里插入圖片描述

3、mysql命令行工具選項 -Ne 的解釋:
-e, --execute=name 表示執行MySQL語句並退出
-N, --skip-column-names 選項表示不要在結果中寫入列名
有無 -N選項的區別如下:

[root@mysql ~]# mysql -uroot -p -e "SHOW DATABASES;"
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+

[root@mysql ~]# mysql -uroot -p -Ne "SHOW DATABASES;"
+--------------------+
| information_schema |
|              mysql |
| performance_schema |
|                sys |
+--------------------+

4、$()是shell的命令替換字符,shell會先執行括號里面的命令,並返回命令執行的標准輸出結果

5、變量名l_t_cmd 定義的是查看表分區的語句,由此得知數據表采用了表分區

6、echo ${l_t_cmd}、echo ${db},使用echo將變量值輸出,使腳本在執行過程中具有可讀性

7、變量名d_t_cmd定義了刪除表分區的語句,即使用ALTER TABLE table_name DROP PARTITION part_name語句刪除表分區

8、INFORMATION_SCHEMA是每個 MySQL 實例中的數據庫,存儲有關 MySQL 服務器維護的所有其他數據庫的詳細信息

9、前面查看見建表語句時,descr列的數字代表的是時間戳,時間戳的值如何得來?
在這里插入圖片描述
通過以下語句獲得,
TO_DAY(date)函數返回日期date距離0000年1月1日的天數。
UNIX_TIMESTAMP(date)函數返回UNIX時間戳,自'1970-01-01 00:00:00'的到當前時間的秒數差

MariaDB [(none)]> SELECT TO_DAYS('2021-07-01 00:00:00');
+--------------------------------+
| TO_DAYS('2021-07-01 00:00:00') |
+--------------------------------+
|                         738337 |
+--------------------------------+
1 row in set (0.00 sec)

MariaDB [(none)]> SELECT UNIX_TIMESTAMP('2021-07-01 00:00:00');
+---------------------------------------+
| UNIX_TIMESTAMP('2021-07-01 00:00:00') |
+---------------------------------------+
|                            1625068800 |
+---------------------------------------+
1 row in set (0.00 sec)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM