Compare commits

...

399 Commits
0.19.0 ... dev

Author SHA1 Message Date
157a5da6f1 Update index.py 2026-11-05 19:19:31 +08:00
7ee5ed5808 up 2026-11-05 19:02:31 +08:00
e8a96959a5 Update install.sh 2026-11-05 18:56:26 +08:00
a4845acbb6 Update index.py 2026-11-05 18:44:11 +08:00
fec638007c Update setting.py 2026-11-05 16:49:15 +08:00
80f7a0de38 Update setting.py 2026-11-05 16:42:39 +08:00
a3bb9ac80a Update setting.py 2026-11-05 16:30:21 +08:00
3dcc6e3349 Update setting.py 2026-11-05 16:28:18 +08:00
60870a4e5d Update setting.py 2026-11-05 16:18:39 +08:00
ea635bc960 Update setting.py 2026-11-05 16:08:12 +08:00
749c8443ee Update setting.py 2026-11-05 16:06:46 +08:00
052120c25e Update setting.py 2026-11-05 16:05:48 +08:00
a2b3b86c43 Update setting.py 2026-11-05 16:05:37 +08:00
6d57e3dd40 Update mw.tpl 2026-11-05 15:45:41 +08:00
a67689d890 Update mw.tpl 2026-11-05 15:36:24 +08:00
b6bffedf06 Update mw.tpl 2026-11-05 15:34:52 +08:00
e07eaf4226 Update mw.tpl 2026-11-05 15:32:05 +08:00
dd9e9d4899 Update mw.tpl 2026-11-05 15:17:19 +08:00
cd1d80915a Update mw.tpl 2026-11-05 15:14:19 +08:00
40f64ab3e8 Update install.sh 2026-11-05 14:55:31 +08:00
69ba921ec4 Update index.py 2026-11-05 14:54:39 +08:00
255fbcd688 Update index.py 2026-11-05 14:35:35 +08:00
24e12b70c8 Update index.py 2026-11-05 14:35:02 +08:00
0feee48ea8 Update install.sh 2026-11-05 14:31:22 +08:00
5cd8c5ae2c Update index.py 2026-11-05 14:28:11 +08:00
28a75eaedc Update index.py 2026-11-05 14:26:12 +08:00
50d0794f4a Update index.py 2026-11-05 14:23:24 +08:00
755e53f4d7 Update index.py 2026-11-05 14:20:13 +08:00
1876027bd2 update 2026-11-05 14:14:23 +08:00
26b06f9bb2 Update index.py 2026-11-05 14:10:37 +08:00
8f67d35260 update 2026-11-05 13:40:46 +08:00
7fa78c78e2 更加优化匹配 2026-11-05 13:37:37 +08:00
ae7276300f Update install.sh 2026-11-05 11:57:54 +08:00
420816ff4e Update requirements.txt 2026-11-05 09:58:54 +08:00
df34a7ef9b Update plugin.py 2026-11-05 00:12:28 +08:00
e1b199c8d5 Update plugin.py 2026-11-05 00:07:29 +08:00
Mr Chen
e6060847ef Merge pull request #965 from midoks/dev
常规更新
2026-11-04 15:52:18 +08:00
7ff1530684 update 2026-11-04 15:35:08 +08:00
cd0ad7488e update 2026-11-04 15:33:18 +08:00
6a0f81154a Update index.py 2026-11-04 15:31:09 +08:00
Mr Chen
096c736c28 Merge pull request #964 from midoks/dev
常规优化
2026-11-04 14:51:09 +08:00
7d01a487dc Merge branch 'master' into dev 2026-11-04 14:47:28 +08:00
ba95ef1537 Update install.sh 2026-11-04 14:43:26 +08:00
01035018c4 Update install.sh 2026-11-04 14:43:07 +08:00
8aa12b979a Update install.sh 2026-11-04 14:40:26 +08:00
98dc9e5bd8 Update tool_cron.py 2026-11-04 14:34:10 +08:00
4ebadc28c9 Update tool_cron.py 2026-11-04 14:32:34 +08:00
02115226fa Update tool_cron.py 2026-11-04 14:31:51 +08:00
f661aea83c Update manticore.conf 2026-11-04 14:17:36 +08:00
cfd3abf97b Update manticore.conf 2026-11-04 14:15:16 +08:00
b5d1c8cfcf Update manticore.conf 2026-11-04 14:12:11 +08:00
98156cc1cb Update sql_mysql.py 2026-11-04 14:01:56 +08:00
33a0dc6014 Update my.cnf 2026-11-04 13:57:38 +08:00
95a6f86e5d Update sql_mysql.py 2026-11-04 13:52:16 +08:00
74ac55b01d Update info.json 2026-11-04 13:50:19 +08:00
518cc78670 Update none.conf 2026-11-04 13:45:04 +08:00
43727decf0 update 2026-11-04 13:12:33 +08:00
599b3a7f4a Update install.sh 2026-11-04 13:05:29 +08:00
bf6c18c57a Update install.sh 2026-11-04 13:04:06 +08:00
34838bb238 update 2026-11-04 12:58:55 +08:00
1a356e516c Update index.py 2026-11-04 12:45:23 +08:00
15e273aa6f Update index.py 2026-11-04 12:44:21 +08:00
Mr Chen
4c3d3bf41d Merge pull request #963 from midoks/dev
常规优化
2026-11-04 12:43:49 +08:00
f782bacc64 update 2026-11-04 12:41:48 +08:00
7e62ab62f9 Update index.py 2026-11-04 11:45:38 +08:00
aaa8644348 Update mariadb.js 2026-11-04 11:43:26 +08:00
53797c7f56 Update index.py 2026-11-04 11:42:18 +08:00
c9302f406e Update my.cnf 2026-11-04 11:10:00 +08:00
7ad881c8ad mysql 同时过滤系统表
replicate-wild-ignore-table = mysql.%
replicate-wild-ignore-table = information_schema.%
replicate-wild-ignore-table = performance_schema.%
replicate-wild-ignore-table = sys.%
2026-11-04 11:06:28 +08:00
015e57f96d update 2026-11-04 10:21:48 +08:00
84b94a172e Update index.py 2026-11-04 10:11:25 +08:00
c1380945ef Update index.py 2026-11-04 10:11:02 +08:00
2d80df003e Update my5.7.cnf 2026-11-04 01:16:28 +08:00
568cdaa0ad Update my5.7.cnf 2026-11-04 01:13:19 +08:00
d11e4807df Update my5.7.cnf 2026-11-04 01:12:00 +08:00
Mr Chen
f6bc08cec1 Merge pull request #962 from midoks/dev
update
2026-11-04 00:47:06 +08:00
d723afb96e update 2026-11-04 00:26:05 +08:00
Mr Chen
6c2aa089f3 Merge pull request #961 from midoks/dev
常规优化
2026-11-04 00:06:02 +08:00
35e1ff2e96 update 2026-11-04 00:04:52 +08:00
bee9e89ed5 Update index.py 2026-11-03 22:46:33 +08:00
d0b622906f Update index.py 2026-11-03 22:37:34 +08:00
56f7edcb55 update 2026-11-03 22:36:17 +08:00
4acbc0363f Merge branch 'master' into dev 2026-11-03 22:26:50 +08:00
79013db685 Merge branch 'master' into dev 2026-11-03 22:19:05 +08:00
Mr Chen
eb5b5e5ce8 Merge pull request #960 from midoks/dev
常规更新
2026-11-03 22:16:20 +08:00
b9e6469635 update 2026-11-03 22:04:11 +08:00
56ab927f8c update 2026-11-03 21:56:19 +08:00
3d74320e76 update 2026-11-03 21:25:14 +08:00
0371eaa37a Update index.py 2026-11-03 17:01:41 +08:00
713dbfcda5 Update index.py 2026-11-03 16:47:50 +08:00
93ef2848ed Update mariadb.js 2026-11-03 16:38:47 +08:00
8750cf0f74 Update mariadb.js 2026-11-03 16:38:38 +08:00
af32a1e54d Update index.py 2026-11-03 16:23:42 +08:00
2a7c63029a Update index.py 2026-11-03 15:56:48 +08:00
f8fe7bea19 Update index.py 2026-11-03 15:55:08 +08:00
ef2814bafe Update index.py 2026-11-03 14:14:09 +08:00
220fef5f4d Update index.py 2026-11-03 14:13:36 +08:00
2835c111d0 update 2026-11-03 14:10:41 +08:00
6d0dcf3112 Update index.py 2026-11-03 14:06:44 +08:00
28307ce8e8 Update index.py 2026-11-03 14:01:04 +08:00
282fbed37d Update index.py 2026-11-03 13:53:13 +08:00
101b6d06bc Update mysql-community.js 2026-11-03 13:46:27 +08:00
8de4c74696 update 2026-11-03 13:45:35 +08:00
ba62972820 update 2026-11-03 13:34:34 +08:00
ec512f50af update 2026-11-03 13:08:43 +08:00
3261f54649 update 2026-11-03 12:28:50 +08:00
ec38ba9e21 update 2026-11-03 12:22:57 +08:00
9e1dc94a08 Update install.sh 2026-11-03 12:19:41 +08:00
40a76ac81e 主从同步模式 切换功能 2026-11-03 12:12:16 +08:00
721245b9ad Update my26.10.cnf 2026-11-03 12:02:37 +08:00
cb4ae9b74f Update my26.7.cnf 2026-11-03 12:01:15 +08:00
Mr Chen
5524ecf4e0 Merge pull request #959 from midoks/dev
常规更新
2026-11-03 12:00:47 +08:00
dbb2718892 update 2026-11-03 11:59:39 +08:00
88fc903d80 update 2026-11-03 11:56:07 +08:00
Mr Chen
242c30f7cb Merge pull request #958 from midoks/dev
常规更新
2026-11-03 11:29:36 +08:00
c944b7c585 update 2026-11-03 11:17:45 +08:00
dc2e2695be update 2026-11-03 11:05:28 +08:00
f5b86ea189 update 2026-11-03 11:04:36 +08:00
b6c2f7f3a1 Update index.py 2026-11-03 10:57:31 +08:00
81003f75b7 Update backup.py 2026-11-03 10:55:25 +08:00
d6dc330083 Update postgresql.js 2026-11-03 10:53:49 +08:00
fd0cbe10fc update 2026-11-03 10:51:15 +08:00
4ed77e82be update 2026-11-03 10:29:58 +08:00
Mr Chen
de0e89f056 Merge pull request #957 from midoks/dev
常规优化
2026-11-03 10:22:32 +08:00
29da5146f6 数据类开启卸载检查 2026-11-03 10:19:24 +08:00
e951089b45 Update index.py 2026-11-03 10:14:05 +08:00
909d65ad83 update 2026-11-03 10:13:20 +08:00
27cac55b8f Update index.py 2026-11-03 10:06:26 +08:00
0ee6ae3713 Update index.py 2026-11-03 09:58:32 +08:00
fb97160cfb Update index.py 2026-11-03 09:58:04 +08:00
96b00526fe Update install.sh 2026-11-03 09:55:18 +08:00
909fe6d0f1 Update sql_postgresql.py 2026-11-03 09:54:01 +08:00
f2e9f4c5e8 update 2026-11-03 09:52:15 +08:00
3b629b1296 Merge branch 'master' into dev 2026-11-02 23:51:58 +08:00
5cee415030 Merge branch 'master' into dev 2026-11-02 23:49:49 +08:00
Mr Chen
141e52d42a Merge pull request #956 from midoks/dev
常规更新
2026-11-02 23:48:47 +08:00
1b21f3c814 Update app.js 2026-11-02 23:46:15 +08:00
4ddc2fef8e update 2026-11-02 23:42:40 +08:00
18b259a5a5 Update app.js 2026-11-02 23:35:06 +08:00
2e2288a691 update 2026-11-02 23:32:29 +08:00
d03ae1db7b Update app.js 2026-11-02 23:15:15 +08:00
418355a571 update 2026-11-02 23:12:34 +08:00
340b53aa62 update 2026-11-02 23:01:21 +08:00
dd0628a7fb Update install.sh 2026-11-02 22:50:47 +08:00
3e5b48d2ad Update index.py 2026-11-02 22:28:54 +08:00
Mr Chen
815148a722 Merge pull request #955 from midoks/dev
常规优化
2026-11-02 22:21:33 +08:00
47aadfd877 Merge branch 'master' into dev 2026-11-02 22:19:31 +08:00
42bfd9a934 update 2026-11-02 22:01:40 +08:00
55df1b7613 Update backup.py 2026-11-02 21:50:01 +08:00
6bc3fc5707 Update index.py 2026-11-02 21:42:33 +08:00
19771181dd update 2026-11-02 21:42:27 +08:00
f0b65332bd Update index.py 2026-11-02 21:28:35 +08:00
7dd8a1eb4f Update index.py 2026-11-02 21:24:39 +08:00
f584c18d7e Update index.py 2026-11-02 21:16:53 +08:00
b023044473 Update index.py 2026-11-02 21:13:07 +08:00
dfa7ffdb53 Update index.py 2026-11-02 21:08:45 +08:00
a5a6eb7e5f update 2026-11-02 21:07:24 +08:00
eac88f1d26 update 2026-11-02 21:03:09 +08:00
518f693948 Update index.py 2026-11-02 20:56:05 +08:00
43684e9b20 update 2026-11-02 20:53:54 +08:00
59a7bb5584 update 2026-11-02 20:49:31 +08:00
f623fd9dcf Update postgresql.js 2026-11-02 20:41:50 +08:00
9db36d45af update 2026-11-02 20:33:57 +08:00
ff5670797a Update backup.py 2026-11-02 20:31:56 +08:00
54ad7e5fd0 update 2026-11-02 20:10:08 +08:00
2970aa4b8c Update index.py 2026-11-02 20:08:36 +08:00
d2e5751542 Update index.py 2026-11-02 20:07:59 +08:00
ba5f6f4958 Update index.py 2026-11-02 20:07:11 +08:00
b220552f92 update 2026-11-02 20:04:47 +08:00
d02981cee5 Update backup.py 2026-11-02 19:46:25 +08:00
96d5246415 Update index.py 2026-11-02 19:35:17 +08:00
ea284049c0 update 2026-11-02 19:02:40 +08:00
5c44bb10d1 Update index.py 2026-11-02 18:55:21 +08:00
c7c834fb75 Update postgresql.js 2026-11-02 18:55:16 +08:00
2ade5e490c update 2026-11-02 18:40:38 +08:00
6c61d3f3c0 Update postgresql.js 2026-11-02 18:30:25 +08:00
ab19878a80 Update mw.tpl 2026-11-02 18:11:02 +08:00
c27abfde3c Update install_mac.sh 2026-11-02 17:54:06 +08:00
411b21cdec Update install_mac.sh 2026-11-02 17:48:46 +08:00
26e21e631d update 2026-11-02 17:46:47 +08:00
Mr Chen
653068f2c2 Merge pull request #954 from midoks/dev
常规优化
2026-11-02 17:42:54 +08:00
188c63826f mysql-community mac 2026-11-02 17:41:02 +08:00
1820fc724f Update install.sh 2026-11-02 17:32:37 +08:00
645519b983 update 2026-11-02 17:27:57 +08:00
f97e015bbc update 2026-11-02 17:22:03 +08:00
9d47a385f5 update 2026-11-02 16:56:59 +08:00
ca06c68d24 update 2026-11-02 16:53:59 +08:00
841873418c update 2026-11-02 16:32:58 +08:00
05a6f093ab update 2026-11-02 16:31:45 +08:00
a916104d33 update 2026-11-02 16:30:09 +08:00
4609c360ac mongodb命令导入 2026-11-02 16:18:22 +08:00
b3acf3647f Update mysql.js 2026-11-02 16:10:51 +08:00
400c9d1276 Update mysql.js 2026-11-02 15:09:57 +08:00
Mr Chen
59bd655bb1 Merge pull request #953 from midoks/dev
常规优化
2026-11-02 07:52:20 +08:00
8227253b74 update 2026-11-02 07:42:26 +08:00
4e5604dc27 Update mariadb.js 2026-11-02 07:36:44 +08:00
2e238e6982 Update index.py 2026-11-02 07:33:01 +08:00
c5df0f256c Update index.py 2026-11-02 07:32:03 +08:00
6bd73131ce Update index.py 2026-11-02 07:29:19 +08:00
309422a41c update 2026-11-02 07:26:34 +08:00
6aa7d9dc20 update 2026-11-02 07:24:45 +08:00
565e1cc882 Update index.py 2026-11-02 07:24:33 +08:00
Mr Chen
5c1e292da9 Merge pull request #952 from midoks/dev
常规优化
2026-11-01 19:44:53 +08:00
6db1ee133d update 2026-11-01 19:35:10 +08:00
Mr Chen
383cec2ee5 Merge pull request #951 from midoks/dev
兼容更新+mysql备份可指定到表备份
2026-11-01 15:45:08 +08:00
dfa2163407 Update plugin.py 2026-11-01 15:32:23 +08:00
ed9a9b7860 Update plugin.py 2026-11-01 15:26:22 +08:00
5af49dc081 Merge branch 'master' into dev 2026-11-01 14:51:45 +08:00
d4f425abf8 备份不走sqlite了 2026-11-01 14:49:39 +08:00
1867ee01f1 update 2026-11-01 14:45:00 +08:00
81fe83e0a1 update 2026-11-01 14:31:42 +08:00
f266ec86c0 Create backup.py 2026-11-01 14:22:44 +08:00
e5d6357fae update 2026-11-01 14:20:52 +08:00
7967b36088 Update backup.py 2026-11-01 14:03:52 +08:00
d7471fe882 Update index.py 2026-11-01 13:56:19 +08:00
b4b67c8f48 update 2026-11-01 13:56:02 +08:00
63ae895f12 Update index.py 2026-11-01 13:53:27 +08:00
5dd77ee747 Update backup.py 2026-11-01 13:50:33 +08:00
6071dfa5f1 Update index.py 2026-11-01 13:46:01 +08:00
11d8d813d2 update 2026-11-01 13:40:40 +08:00
f337a60dc1 Update index.py 2026-11-01 13:16:07 +08:00
33f66ab3b1 Update index.py 2026-11-01 13:14:27 +08:00
eb71732d20 Update index.py 2026-11-01 13:07:09 +08:00
fbc9340960 Update index.py 2026-11-01 13:01:15 +08:00
a2f14f4121 Update index.py 2026-11-01 12:26:38 +08:00
ce8c7474ce Update backup.py 2026-11-01 12:24:13 +08:00
85d9f1409a Update index.py 2026-11-01 12:19:10 +08:00
c29dfee004 Update backup.py 2026-11-01 12:12:04 +08:00
618f938462 update 2026-11-01 12:08:34 +08:00
4e7927f9bc Update crontab.py 2026-11-01 03:24:26 +08:00
212f29438d Update crontab.py 2026-11-01 03:16:28 +08:00
3b6d9c3310 Update crontab.py 2026-11-01 03:15:13 +08:00
c01cb01d71 Update crontab.py 2026-11-01 03:14:31 +08:00
712863b766 Update crontab.py 2026-11-01 03:11:14 +08:00
601a80950f Update crontab.py 2026-11-01 03:10:21 +08:00
9f46ceac33 Update crontab.js 2026-11-01 03:08:58 +08:00
ad9b9be7fe Update crontab.py 2026-11-01 03:05:36 +08:00
2be6ac36ef Update crontab.py 2026-11-01 03:04:11 +08:00
fdb8ca205f Update crontab.py 2026-11-01 03:01:49 +08:00
f1024c165a Update crontab.py 2026-11-01 02:58:01 +08:00
9efc85f10d Update crontab.py 2026-11-01 02:52:33 +08:00
dd592b40ee Update crontab.py 2026-11-01 02:52:02 +08:00
9103646150 Update crontab.py 2026-11-01 02:50:05 +08:00
cae2680862 Update crontab.py 2026-11-01 02:48:41 +08:00
e3099a946b Update crontab.py 2026-11-01 02:44:49 +08:00
3f1da50025 Update crontab.py 2026-11-01 02:41:36 +08:00
fbd70eb4f9 Update crontab.py 2026-11-01 02:40:11 +08:00
ef0d6d5265 Update crontab.py 2026-11-01 02:36:43 +08:00
1e6932cd01 Update crontab.py 2026-11-01 02:36:08 +08:00
d173586d49 Update crontab.py 2026-11-01 02:28:51 +08:00
717269dadc Update crontab.py 2026-11-01 02:25:23 +08:00
21c4f93e02 Update crontab.py 2026-11-01 02:18:09 +08:00
c36a03bfb3 Update index.py 2026-11-01 02:12:49 +08:00
a71927917c Update index.py 2026-11-01 02:06:55 +08:00
2f5d5835c5 Update config.inc.php 2026-11-01 01:46:11 +08:00
e95b42df77 Update __init__.py 2026-11-01 01:41:09 +08:00
5c6dbbbb0c Update index.py 2026-11-01 01:27:59 +08:00
a151516eab Update index.py 2026-11-01 01:16:10 +08:00
3a590c7feb Update index.py 2026-11-01 01:12:08 +08:00
e9f0e1962e update 2026-11-01 01:10:39 +08:00
c4fda1362d Update mw.py 2026-11-01 01:05:35 +08:00
f31343b2a5 Update index.py 2026-11-01 01:00:10 +08:00
90b414d373 Update index.py 2026-11-01 00:55:03 +08:00
3eab70db4c Update index.py 2026-11-01 00:46:11 +08:00
e0810bb8d6 Update index.py 2026-11-01 00:45:15 +08:00
96a32d5c8f 更加公用 2026-11-01 00:44:10 +08:00
d45cfb5fe8 Update crontab.js 2026-11-01 00:29:32 +08:00
08753ae96d mysql支持表备份 2026-11-01 00:27:45 +08:00
465e55848f Update crontab.py 2026-10-31 23:51:28 +08:00
4492a97155 Update crontab.js 2026-10-31 23:41:38 +08:00
ba46d568bf Update crontab.js 2026-10-31 22:55:35 +08:00
d87d5d5349 Update crontab.js 2026-10-31 18:54:29 +08:00
76ea3e3375 update 2026-10-31 18:54:26 +08:00
ef47145135 Update crontab.js 2026-10-31 18:12:30 +08:00
43a9ee7368 Update crontab.py 2026-10-31 18:12:24 +08:00
6646e0c46c Update crontab.py 2026-10-31 18:01:10 +08:00
535dbb2e37 Update __init__.py 2026-10-31 18:01:03 +08:00
035953c7f5 Update install.sh 2026-10-31 18:00:28 +08:00
6a9ce81d46 update 2026-10-31 17:16:19 +08:00
f2a6824632 Update ssh_terminal.py 2026-10-31 11:57:54 +08:00
594976373e Update requirements.txt 2026-10-31 11:54:09 +08:00
45704f1c31 update 2026-10-30 17:07:22 +08:00
ce57885343 Create rapira85.toml 2026-10-30 16:55:33 +08:00
4d143ef959 Update crontab.js 2026-10-30 10:47:18 +08:00
9a0f9a759c Update install.sh 2026-10-30 10:10:34 +08:00
6341f00f46 update 2026-10-30 10:09:58 +08:00
f517568251 Update crontab.js 2026-10-29 21:02:44 +08:00
1ff6d0c2cb Update crontab.js 2026-10-29 19:17:44 +08:00
5e28039573 update 2026-10-29 18:36:48 +08:00
Mr Chen
d7757bee0d Merge pull request #949 from midoks/dev
update
2026-10-29 12:01:57 +08:00
6b18511708 Update install.sh 2026-10-29 12:00:41 +08:00
4a3e0791d3 update 2026-10-29 11:52:00 +08:00
7c25d3f6c3 Update install.sh 2026-10-29 11:41:54 +08:00
8ef38674d7 Update install.sh 2026-10-29 11:24:40 +08:00
e84cbf1d76 Update install.sh 2026-10-29 11:24:24 +08:00
14f622d252 Update install.sh 2026-10-29 11:16:08 +08:00
8bb2bfacdc Update install.sh 2026-10-29 11:13:52 +08:00
191c4b1331 Update install.sh 2026-10-29 11:11:41 +08:00
7bed2b977e update 2026-10-29 11:11:28 +08:00
b6c09b2b37 update 2026-10-29 11:03:15 +08:00
Mr Chen
1bd5251dc0 Merge pull request #948 from midoks/dev
更新优化
2026-10-28 10:40:32 +08:00
ecf1b6b600 Update install.sh 2026-10-27 23:03:09 +08:00
22cca82967 Update install.sh 2026-10-27 23:02:43 +08:00
cd66e42b1a Update install.sh 2026-10-27 23:00:26 +08:00
d887fa1b50 Update install.sh 2026-10-27 22:59:57 +08:00
55870ca08a Update my9.7.cnf 2026-10-27 22:51:21 +08:00
2ce1d49386 Update install_generic.sh 2026-10-27 22:47:35 +08:00
a0226ccbcd Update install_generic.sh 2026-10-27 22:47:02 +08:00
de7c14ec62 Update index.py 2026-10-27 22:42:03 +08:00
0c2cfd6d9a Update index.py 2026-10-27 22:41:21 +08:00
4ca78b9a91 Update my26.10.cnf 2026-10-27 22:37:56 +08:00
8219c2d2ed Update install_generic.sh 2026-10-27 22:31:47 +08:00
9f22ce949c Update install_generic.sh 2026-10-27 22:28:29 +08:00
d76c21c54b Update install_generic.sh 2026-10-27 22:28:12 +08:00
30c5cee81a update 2026-10-27 22:24:42 +08:00
e2d0ac6d89 update 2026-10-27 22:11:37 +08:00
3578a65d6e Update my9.7.cnf 2026-10-27 22:04:14 +08:00
c8331b800b update 2026-10-27 21:58:20 +08:00
1e7dc18c21 update 2026-10-27 21:46:06 +08:00
046da1868e Update install_generic.sh 2026-10-27 21:38:37 +08:00
ef7068ebd2 Update install_generic.sh 2026-10-27 21:37:47 +08:00
0525667032 Update install_generic.sh 2026-10-27 21:34:15 +08:00
6198ca02da Update install_generic.sh 2026-10-27 21:32:05 +08:00
4d4fd90fc6 Update install.sh 2026-10-27 21:29:58 +08:00
acfc4d710b Update install.sh 2026-10-27 21:29:43 +08:00
4fd12f4d73 update 2026-10-27 21:23:42 +08:00
9a8bb9f94b update 2026-10-27 21:22:30 +08:00
170f758bc9 Update install.sh 2026-10-27 21:19:34 +08:00
8b7d563fac update 2026-10-27 21:18:03 +08:00
6f9e0cdd8f update 2026-10-27 21:16:58 +08:00
0a3af7a0c0 Create install_generic.sh 2026-10-27 21:16:25 +08:00
c90a2facac update 2026-10-27 21:15:35 +08:00
92d56bddab update 2026-10-27 21:07:39 +08:00
a3bab2da47 Update install.sh 2026-10-27 21:02:19 +08:00
d51a3ac1f7 Update info.json 2026-10-27 20:45:25 +08:00
04774bddc3 update 2026-10-27 20:45:00 +08:00
770f1532da update 2026-10-27 17:47:37 +08:00
d09872c2f3 update 2026-10-27 17:30:36 +08:00
e77369cd25 Update install.sh 2026-10-27 17:12:00 +08:00
69897a208c update 2026-10-27 17:10:57 +08:00
1f5c5ac66e update 2026-10-27 17:08:36 +08:00
3a7f8f09cb Update opcache.sh 2026-10-26 13:13:39 +08:00
77d2b9e323 update 2026-10-26 13:11:27 +08:00
d56c271cc4 update 2026-10-26 04:16:03 +08:00
b4aecf5d0c update 2026-10-26 04:15:29 +08:00
e55e23c845 Update rapira.js 2026-10-26 04:05:37 +08:00
e2977dbbc4 Update mcrypt.sh 2026-10-26 04:04:34 +08:00
8ad94ffeff Update install.sh 2026-10-26 04:02:58 +08:00
c94ff04dcf update 2026-10-26 04:00:20 +08:00
65f10ca22f Update sodium.sh 2026-10-26 03:53:59 +08:00
a1127b3bc0 Update sodium.sh 2026-10-26 03:52:48 +08:00
81c16d1a3d update 2026-10-26 03:47:17 +08:00
b1b4c82457 Update rapira.toml 2026-10-26 03:46:09 +08:00
515b22b103 update 2026-10-26 03:45:19 +08:00
c200165057 update 2026-10-26 03:24:02 +08:00
64c30893d5 update 2026-10-26 03:09:50 +08:00
98b8dce5fd up 2026-10-26 03:06:09 +08:00
0d9b7b6edf Update gd_old.sh 2026-10-26 02:59:15 +08:00
b72bb1fa87 update 2026-10-26 02:58:58 +08:00
d85131266c update 2026-10-26 02:56:59 +08:00
22da275f5b up 2026-10-26 02:51:34 +08:00
f6d65b9e33 update 2026-10-26 02:49:41 +08:00
ebc07becd0 update 2026-10-26 02:48:03 +08:00
024f2c2369 update 2026-10-26 02:45:33 +08:00
2b93fb684b update 2026-10-26 02:43:27 +08:00
b2daf6bf65 update 2026-10-26 02:37:33 +08:00
3ee0f553e9 update 2026-10-26 02:26:03 +08:00
f206da8278 Update apcu.sh 2026-10-26 02:07:49 +08:00
edbaeb37f5 update 2026-10-26 02:07:42 +08:00
46847833d0 update 2026-10-26 01:57:13 +08:00
4303a62b1b update 2026-10-26 01:12:09 +08:00
d6d5babf81 Update dispatcher.toml 2026-10-26 00:46:27 +08:00
8e5b10bda3 Update worker.toml 2026-10-26 00:45:45 +08:00
8e54ee987c Update index.py 2026-10-26 00:42:09 +08:00
929b30ce73 update 2026-10-26 00:38:38 +08:00
c085fa7066 update 2026-10-26 00:30:21 +08:00
783e71f189 update 2026-10-26 00:18:37 +08:00
ae1ffd313c Update doh.conf 2026-10-25 22:46:56 +08:00
122c0b5f64 Update doh.conf 2026-10-25 12:53:13 +08:00
21e496f22e Update doh.conf 2026-10-25 12:52:25 +08:00
d92b3039e2 Update doh.conf 2026-10-25 12:49:37 +08:00
ea57812191 Update info.json 2026-10-25 12:46:02 +08:00
d72238df45 update 2026-10-25 12:45:22 +08:00
55aab8d86d Update install.sh 2026-10-25 12:34:49 +08:00
f8d4d9e4cf update 2026-10-25 12:32:30 +08:00
90afa6446c Update install.sh 2026-10-25 09:58:41 +08:00
5e468c548a Update install.sh 2026-10-25 09:58:16 +08:00
48f4521ef6 Update install.sh 2026-10-25 09:55:12 +08:00
ccd48cecfb update 2026-10-25 09:52:31 +08:00
0757638b2e Update install.sh 2026-10-25 09:46:55 +08:00
68cb547d5f update 2026-10-25 08:13:29 +08:00
1f7c494d82 Update install.sh 2026-10-24 14:58:04 +08:00
Mr Chen
8e58783964 Merge pull request #947 from midoks/dev
redis在线更新支持
2026-10-24 14:14:35 +08:00
bfdc0639b6 update 2026-10-24 14:12:33 +08:00
337a7d87e4 Update install.sh 2026-10-24 14:08:47 +08:00
38c062220c redis 在线升级支持 2026-10-24 14:01:26 +08:00
f639acec86 Merge branch 'master' into dev 2026-10-24 12:54:12 +08:00
02ba38a01a Update install.sh 2026-10-24 12:30:18 +08:00
ea8487b14c up 2026-10-24 12:27:40 +08:00
243 changed files with 12020 additions and 4057 deletions

View File

@@ -142,6 +142,7 @@ def initConf():
"/www/server/rsyncd",
"/www/server/acme_pandominassl_apply",
"/www/server/sphinx/index",
"/www/server/manticoresearch",
"/www/server/mongodb/logs",
"/www/server/php/53/var/log",
"/www/server/php/54/var/log",

View File

@@ -37,6 +37,7 @@ class nosqlMemcached():
__DB_HOST = '127.0.0.1'
__DB_CONN = None
__DB_ERR = None
__DB_STATUS = None
__DB_LOCAL = None
@@ -48,19 +49,36 @@ class nosqlMemcached():
if self.__DB_HOST in ['127.0.0.1', 'localhost']:
mem_path = "{}/memcached".format(mw.getServerDir())
if not os.path.exists(mem_path): return False
if not os.path.exists(mem_path):
self.__DB_STATUS = 'not_installed'
return False
if not self.__DB_LOCAL:
if not self.__config:
self.__DB_STATUS = 'not_installed'
return False
self.__DB_PORT = int(self.__config['port'])
try:
self.__DB_CONN = pymemcache.client.base.PooledClient((self.__DB_HOST,self.__DB_PORT), max_pool_size=4)
# PooledClient 是惰性连接,探测一次,服务未启动时及时返回 False
self.__DB_CONN.version()
self.__DB_STATUS = None
return self.__DB_CONN
except pymemcache.exceptions.MemcacheError:
self.__DB_STATUS = 'not_running'
return False
except (ConnectionRefusedError, OSError):
self.__DB_STATUS = 'not_running'
return False
except Exception:
self.__DB_ERR = mw.getTracebackInfo()
self.__DB_STATUS = 'not_running'
return False
# 连接状态:not_installed 未安装 / not_running 未启动 / None 正常
def get_status(self):
return self.__DB_STATUS
# 获取配置项
def get_options(self, get=None):
@@ -95,11 +113,20 @@ class nosqlMemcachedCtr():
instance = nosqlMemcached()
return instance
def _connect(self, sid):
obj = self.getInstanceBySid(sid)
conn = obj.conn()
if conn is False:
if obj.get_status() == 'not_installed':
return None, mw.returnData(False, '未安装')
return None, mw.returnData(False, '未启动')
return conn, None
def getItems(self, args):
sid = args['sid']
mem_instance = self.getInstanceBySid(sid).conn()
if mem_instance is False:
return mw.returnData(False,'无法链接')
mem_instance, err = self._connect(sid)
if err:
return err
result = {}
m_items = mem_instance.stats('items')
@@ -122,9 +149,9 @@ class nosqlMemcachedCtr():
def getKeyList(self, args):
sid = args['sid']
mem_instance = self.getInstanceBySid(sid).conn()
if mem_instance is False:
return mw.returnData(False,'无法链接')
mem_instance, err = self._connect(sid)
if err:
return err
p = 1
@@ -194,9 +221,9 @@ class nosqlMemcachedCtr():
def delVal(self, args):
sid = args['sid']
mem_instance = self.getInstanceBySid(sid).conn()
if mem_instance is False:
return mw.returnData(False,'无法链接')
mem_instance, err = self._connect(sid)
if err:
return err
key = args['key']
mem_instance.delete(key)
@@ -205,9 +232,9 @@ class nosqlMemcachedCtr():
def setKv(self, args):
sid = args['sid']
mem_instance = self.getInstanceBySid(sid).conn()
if mem_instance is False:
return mw.returnData(False,'无法链接')
mem_instance, err = self._connect(sid)
if err:
return err
key = args['key']
val = args['val']
@@ -217,9 +244,9 @@ class nosqlMemcachedCtr():
def clear(self, args):
sid = args['sid']
mem_instance = self.getInstanceBySid(sid).conn()
if mem_instance is False:
return mw.returnData(False,'无法链接')
mem_instance, err = self._connect(sid)
if err:
return err
mem_instance.flush_all()
return mw.returnData(True,'清空成功!')

View File

@@ -127,6 +127,7 @@ class nosqlMongodb():
__DB_HOST = '127.0.0.1'
__DB_CONN = None
__DB_ERR = None
__DB_STATUS = None
__DB_LOCAL = None
@@ -138,29 +139,51 @@ class nosqlMongodb():
if self.__DB_HOST in ['127.0.0.1', 'localhost']:
mgdb_path = "{}/mongodb".format(mw.getServerDir())
if not os.path.exists(mgdb_path): return False
if not os.path.exists(mgdb_path):
self.__DB_STATUS = 'not_installed'
return False
if not self.__DB_LOCAL:
if not self.__config:
self.__DB_STATUS = 'not_installed'
return False
self.__DB_PORT = int(self.__config['port'])
auth = getConfAuth()
port = getConfPort()
mg_root = pSqliteDb('config').where('id=?', (1,)).getField('mg_root')
# print(auth,self.__DB_HOST,port, self.__DB_PASS)
try:
if auth == 'disabled':
self.__DB_CONN = pymongo.MongoClient(host=self.__DB_HOST, port=port, directConnection=True)
self.__DB_CONN = pymongo.MongoClient(host=self.__DB_HOST, port=port, directConnection=True, serverSelectionTimeoutMS=3000)
else:
self.__DB_CONN = pymongo.MongoClient(host=self.__DB_HOST, port=port, directConnection=True, username='root',password=mg_root)
self.__DB_CONN = pymongo.MongoClient(host=self.__DB_HOST, port=port, directConnection=True, username='root',password=mg_root, serverSelectionTimeoutMS=3000)
self.__DB_CONN.admin.command('ping')
# 节点处于 recovering/startup 时 ping 仍会成功,但读写会抛 NotPrimaryError
try:
hello = self.__DB_CONN.admin.command('hello')
except Exception:
# MongoDB < 5.0 没有 hello 命令
hello = self.__DB_CONN.admin.command('isMaster')
if not (hello.get('isWritablePrimary') or hello.get('ismaster') or hello.get('secondary')):
self.__DB_ERR = 'MongoDB 节点当前不是 primary 或 secondary 状态'
return False
self.__DB_STATUS = None
self.__DB_ERR = None
return self.__DB_CONN
except pymongo.errors.ConnectionFailure:
self.__DB_STATUS = 'not_running'
return False
except Exception as e:
# print(e)
self.__DB_ERR = mw.getTracebackInfo()
except Exception:
self.__DB_STATUS = 'not_running'
return False
# 连接状态:not_installed 未安装 / not_running 未启动 / None 正常
def get_status(self):
return self.__DB_STATUS
def get_err(self):
return self.__DB_ERR
# 获取配置项
def get_options(self, get=None):
result = {}
@@ -202,11 +225,23 @@ class nosqlMongodbCtr():
instance = nosqlMongodb()
return instance
def _connect(self, sid):
obj = self.getInstanceBySid(sid)
conn = obj.mgdb_conn()
if conn is False:
if obj.get_status() == 'not_installed':
return None, mw.returnData(False, '未安装')
err = obj.get_err()
if err:
return None, mw.returnData(False, err)
return None, mw.returnData(False, '未启动')
return conn, None
def getDbList(self, args):
sid = args['sid']
mgdb_instance = self.getInstanceBySid(sid).mgdb_conn()
if mgdb_instance is False:
return mw.returnData(False,'无法链接')
mgdb_instance, err = self._connect(sid)
if err:
return err
result = {}
doc_list = mgdb_instance.list_database_names()
@@ -221,9 +256,9 @@ class nosqlMongodbCtr():
sid = args['sid']
name = args['name']
mgdb_instance = self.getInstanceBySid(sid).mgdb_conn()
if mgdb_instance is False:
return mw.returnData(False,'无法链接.')
mgdb_instance, err = self._connect(sid)
if err:
return err
result = {}
collections = mgdb_instance[name].list_collection_names()
@@ -242,9 +277,9 @@ class nosqlMongodbCtr():
if 'size' in args:
size = args['size']
mgdb_instance = self.getInstanceBySid(sid).mgdb_conn()
if mgdb_instance is False:
return mw.returnData(False,'无法链接')
mgdb_instance, err = self._connect(sid)
if err:
return err
db_instance = mgdb_instance[db]
collection_instance = db_instance[collection]
@@ -303,9 +338,9 @@ class nosqlMongodbCtr():
db = args['db']
collection = args['collection']
mgdb_instance = self.getInstanceBySid(sid).mgdb_conn()
if mgdb_instance is False:
return mw.returnData(False,'无法链接')
mgdb_instance, err = self._connect(sid)
if err:
return err
db_instance = mgdb_instance[db]
collection_instance = db_instance[collection]

View File

@@ -32,6 +32,7 @@ class nosqlRedis():
__DB_HOST = '127.0.0.1'
__DB_CONN = None
__DB_ERR = None
__DB_STATUS = None
__DB_LOCAL = None
@@ -44,9 +45,13 @@ class nosqlRedis():
if self.__DB_HOST in ['127.0.0.1', 'localhost']:
redis_path = "{}/redis".format(mw.getServerDir())
if not os.path.exists(redis_path):
self.__DB_STATUS = 'not_installed'
return False
if not self.__DB_LOCAL:
if not self.__config:
self.__DB_STATUS = 'not_installed'
return False
self.__DB_PASS = self.__config['requirepass']
self.__DB_PORT = int(self.__config['port'])
@@ -55,13 +60,20 @@ class nosqlRedis():
redis_pool = redis.ConnectionPool(host=self.__DB_HOST, port=self.__DB_PORT, password=self.__DB_PASS, db=db_idx, socket_timeout=3)
self.__DB_CONN = redis.Redis(connection_pool=redis_pool)
self.__DB_CONN.ping()
self.__DB_STATUS = None
return self.__DB_CONN
except redis.exceptions.ConnectionError:
self.__DB_STATUS = 'not_running'
return False
except Exception:
self.__DB_ERR = mw.getTracebackInfo()
self.__DB_STATUS = 'not_running'
return False
# 连接状态:not_installed 未安装 / not_running 未启动 / None 正常
def get_status(self):
return self.__DB_STATUS
# 获取配置项
def get_options(self, get=None):
@@ -112,12 +124,21 @@ class nosqlRedisCtr():
instance = nosqlRedis()
return instance
def _connect(self, sid, idx=0):
obj = self.getInstanceBySid(sid)
conn = obj.redis_conn(idx)
if conn is False:
if obj.get_status() == 'not_installed':
return None, mw.returnData(False, '未安装')
return None, mw.returnData(False, '未启动')
return conn, None
def getList(self, args):
sid = args['sid']
redis_instance = self.getInstanceBySid(sid).redis_conn(0)
if redis_instance is False:
return mw.returnData(False,'无法链接')
redis_instance, err = self._connect(sid, 0)
if err:
return err
redis_info = redis_instance.info()
@@ -166,7 +187,9 @@ class nosqlRedisCtr():
if 'search' in args and args['search'] != '':
search = args['search']
redis_instance = self.getInstanceBySid(sid).redis_conn(idx)
redis_instance, err = self._connect(sid, idx)
if err:
return err
total = redis_instance.dbsize()
@@ -251,7 +274,9 @@ class nosqlRedisCtr():
val = args["val"]
endtime = args["endtime"]
redis_instance = self.getInstanceBySid(sid).redis_conn(idx)
redis_instance, err = self._connect(sid, idx)
if err:
return err
redis_info = redis_instance.info()
if redis_info['role'] == 'slave':
@@ -268,7 +293,9 @@ class nosqlRedisCtr():
sid = args['sid']
idx = args['idx']
name = args["name"]
redis_instance = self.getInstanceBySid(sid).redis_conn(idx)
redis_instance, err = self._connect(sid, idx)
if err:
return err
redis_info = redis_instance.info()
if redis_info['role'] == 'slave':
@@ -281,7 +308,9 @@ class nosqlRedisCtr():
sid = args['sid']
idx = args['idx']
keys = args["keys"]
redis_instance = self.getInstanceBySid(sid).redis_conn(idx)
redis_instance, err = self._connect(sid, idx)
if err:
return err
redis_info = redis_instance.info()
if redis_info['role'] == 'slave':
@@ -297,7 +326,9 @@ class nosqlRedisCtr():
idxs = args['idxs']
for idx in idxs:
redis_instance = self.getInstanceBySid(sid).redis_conn(idx)
redis_instance, err = self._connect(sid, idx)
if err:
return err
redis_info = redis_instance.info()
if redis_info['role'] == 'slave':

View File

@@ -31,6 +31,7 @@ class nosqlMySQL():
__DB_HOST = '127.0.0.1'
__DB_CONN = None
__DB_ERR = None
__DB_STATUS = None
__DB_SOCKET = None
__DB_LOCAL = None
@@ -45,13 +46,19 @@ class nosqlMySQL():
def conn(self):
if self.__sid is None:
self.__DB_STATUS = 'not_installed'
return False
if self.__sid is not None:
mycnf_path = "{}/{}/etc/my.cnf".format(mw.getServerDir(),self.__sid)
if not os.path.exists(mycnf_path):
self.__DB_STATUS = 'not_installed'
return False
if not self.__config:
self.__DB_STATUS = 'not_installed'
return False
self.__DB_PORT = int(self.__config['port'])
self.__DB_USER = self.__config['username']
self.__DB_PASS = self.__config['password']
@@ -65,11 +72,19 @@ class nosqlMySQL():
if self.__DB_SOCKET != '':
db.setSocket(self.__DB_SOCKET)
# 实际连通性检查:服务未启动或账号错误时返回 False,调用方统一提示
db.query('select 1')
self.__DB_STATUS = None
return db
except Exception:
self.__DB_ERR = mw.get_error_info()
self.__DB_ERR = mw.getTracebackInfo()
self.__DB_STATUS = 'not_running'
return False
# 连接状态:not_installed 未安装 / not_running 未启动 / None 正常
def get_status(self):
return self.__DB_STATUS
def sqliteDb(self, db_pos_name, dbname='databases'):
mydb_path = mw.getServerDir() +'/'+db_pos_name
name = 'mysql'
@@ -84,7 +99,7 @@ class nosqlMySQL():
result['host'] = '127.0.0.1'
result['username'] = 'root'
if sid in ['mysql', 'mysql-apt', 'mysql-yum', 'mysql-community']:
if sid in ['mysql', 'mysql-apt', 'mysql-yum', 'mysql-community','mariadb']:
my_cnf_path = "{}/{}/etc/my.cnf".format(mw.getServerDir(),sid)
if not os.path.exists(my_cnf_path):
return False
@@ -136,6 +151,10 @@ class nosqlMySQL():
local_mysql_yum = "{}/mysql-community/etc/my.cnf".format(mw.getServerDir())
if os.path.exists(local_mysql_yum):
data.append({'name':'本地服务器[Tar]', 'val':'mysql-community'})
local_mysql_yum = "{}/mariadb/etc/my.cnf".format(mw.getServerDir())
if os.path.exists(local_mysql_yum):
data.append({'name':'本地服务器[mariadb]', 'val':'mariadb'})
return mw.returnData(True, 'ok', data)
@singleton
@@ -153,11 +172,20 @@ class nosqlMySQLCtr():
instance.setSid(sid)
return instance
def _connect(self, sid):
obj = self.getInstanceBySid(sid)
conn = obj.conn()
if conn is False:
if obj.get_status() == 'not_installed':
return None, mw.returnData(False, '未安装')
return None, mw.returnData(False, '未启动')
return conn, None
def getDbList(self, args):
sid = args['sid']
my_instance = self.getInstanceBySid(sid).conn()
if my_instance is False:
return mw.returnData(False,'无法链接')
my_instance, err = self._connect(sid)
if err:
return err
result = {}
db_list = my_instance.query('show databases')
@@ -172,9 +200,9 @@ class nosqlMySQLCtr():
sid = args['sid']
db = args['db']
my_instance = self.getInstanceBySid(sid).conn()
if my_instance is False:
return mw.returnData(False,'无法链接')
my_instance, err = self._connect(sid)
if err:
return err
sql = "select * from information_schema.tables where table_schema = '"+db+"'"
table_list = my_instance.query(sql)
@@ -226,9 +254,9 @@ class nosqlMySQLCtr():
else:
where_sql = ' where '+args_where['field'] + " like '%"+args_where['value']+"%' "
my_instance = self.getInstanceBySid(sid).conn()
if my_instance is False:
return mw.returnData(False,'无法链接')
my_instance, err = self._connect(sid)
if err:
return err
my_instance.setDbName(db)
sql = 'select count(*) as num from ' + table + where_sql
@@ -268,9 +296,9 @@ class nosqlMySQLCtr():
sql = 'show processlist';
sid = args['sid']
my_instance = self.getInstanceBySid(sid).conn()
if my_instance is False:
return mw.returnData(False,'无法链接')
my_instance, err = self._connect(sid)
if err:
return err
result = my_instance.query(sql)
rdata = {}
@@ -281,9 +309,9 @@ class nosqlMySQLCtr():
sql = 'show status';
sid = args['sid']
my_instance = self.getInstanceBySid(sid).conn()
if my_instance is False:
return mw.returnData(False,'无法链接')
my_instance, err = self._connect(sid)
if err:
return err
result = my_instance.query(sql)
rdata = {}
@@ -294,9 +322,9 @@ class nosqlMySQLCtr():
sql = "show status like 'Com_%'";
sid = args['sid']
my_instance = self.getInstanceBySid(sid).conn()
if my_instance is False:
return mw.returnData(False,'无法链接')
my_instance, err = self._connect(sid)
if err:
return err
result = my_instance.query(sql)
rdata = {}
@@ -331,9 +359,9 @@ class nosqlMySQLCtr():
def getNetList(self, args):
from datetime import datetime
sid = args['sid']
my_instance = self.getInstanceBySid(sid).conn()
if my_instance is False:
return mw.returnData(False,'无法链接')
my_instance, err = self._connect(sid)
if err:
return err
rdata = []
row = {}
@@ -369,9 +397,9 @@ class nosqlMySQLCtr():
def getTopnList(self, args):
sid = args['sid']
my_instance = self.getInstanceBySid(sid).conn()
if my_instance is False:
return mw.returnData(False,'无法链接')
my_instance, err = self._connect(sid)
if err:
return err
is_performance_schema = my_instance.find("SELECT @@performance_schema")
if is_performance_schema is None:
@@ -399,9 +427,9 @@ class nosqlMySQLCtr():
# 查看重复或冗余的索引
def getRedundantIndexes(self, args):
sid = args['sid']
my_instance = self.getInstanceBySid(sid).conn()
if my_instance is False:
return mw.returnData(False,'无法链接')
my_instance, err = self._connect(sid)
if err:
return err
is_performance_schema = my_instance.find("SELECT @@performance_schema")
if is_performance_schema["@@performance_schema"] == 0:
@@ -417,9 +445,9 @@ class nosqlMySQLCtr():
def redundantIndexesCmd(self, args):
sid = args['sid']
my_instance = self.getInstanceBySid(sid).conn()
if my_instance is False:
return mw.returnData(False,'无法链接')
my_instance, err = self._connect(sid)
if err:
return err
is_performance_schema = my_instance.find("SELECT @@performance_schema")
if is_performance_schema["@@performance_schema"] == 0:
@@ -442,28 +470,47 @@ class nosqlMySQLCtr():
from decimal import Decimal
sid = args['sid']
my_instance = self.getInstanceBySid(sid).conn()
if my_instance is False:
return mw.returnData(False,'无法链接')
my_instance, err = self._connect(sid)
if err:
return err
my_instance.execute("SET sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY',''))")
# ANY_VALUE 是 MySQL 5.7+ 的函数,MariaDB 不支持(报 FUNCTION ANY_VALUE does not exist);
# 上面已去掉 ONLY_FULL_GROUP_BY,MariaDB 可直接取非聚合字段
ver = my_instance.find("SELECT @@version as db_version")
is_mariadb = ver is not None and 'MariaDB' in str(ver.get('db_version', ''))
def any_val(expr):
return expr if is_mariadb else 'ANY_VALUE(' + expr + ')'
data = my_instance.query(
"""
SELECT t.TABLE_SCHEMA as TABLE_SCHEMA, t.TABLE_NAME as TABLE_NAME,
ANY_VALUE(t.ENGINE) as ENGINE,
ANY_VALUE(IFNULL(t.DATA_LENGTH/1024/1024/1024, 0)) as DATA_LENGTH,
ANY_VALUE(IFNULL(t.INDEX_LENGTH/1024/1024/1024, 0)) as INDEX_LENGTH,
ANY_VALUE(IFNULL((t.DATA_LENGTH+t.INDEX_LENGTH)/1024/1024/1024, 0)) AS TOTAL_LENGTH,
ANY_VALUE(c.column_name) AS COLUMN_NAME, ANY_VALUE(c.data_type) AS DATA_TYPE,
ANY_VALUE(c.COLUMN_TYPE) AS COLUMN_TYPE,
ANY_VALUE(t.AUTO_INCREMENT) AS AUTO_INCREMENT,
ANY_VALUE(locate('unsigned', c.COLUMN_TYPE) = 0) AS IS_SIGNED
FROM information_schema.TABLES t
JOIN information_schema.COLUMNS c ON t.TABLE_SCHEMA = c.TABLE_SCHEMA AND t.table_name=c.table_name
WHERE t.TABLE_SCHEMA NOT IN ('mysql', 'information_schema', 'performance_schema', 'sys')
GROUP BY t.TABLE_SCHEMA, t.TABLE_NAME
{engine} as ENGINE,
{data_length} as DATA_LENGTH,
{index_length} as INDEX_LENGTH,
{total_length} AS TOTAL_LENGTH,
{column_name} AS COLUMN_NAME, {data_type} AS DATA_TYPE,
{column_type} AS COLUMN_TYPE,
{auto_increment} AS AUTO_INCREMENT,
{is_signed} AS IS_SIGNED
FROM information_schema.TABLES t
JOIN information_schema.COLUMNS c ON t.TABLE_SCHEMA = c.TABLE_SCHEMA AND t.table_name=c.table_name
WHERE t.TABLE_SCHEMA NOT IN ('mysql', 'information_schema', 'performance_schema', 'sys')
GROUP BY t.TABLE_SCHEMA, t.TABLE_NAME
ORDER BY TOTAL_LENGTH DESC, AUTO_INCREMENT DESC
"""
""".format(
engine=any_val("t.ENGINE"),
data_length=any_val("IFNULL(t.DATA_LENGTH/1024/1024/1024, 0)"),
index_length=any_val("IFNULL(t.INDEX_LENGTH/1024/1024/1024, 0)"),
total_length=any_val("IFNULL((t.DATA_LENGTH+t.INDEX_LENGTH)/1024/1024/1024, 0)"),
column_name=any_val("c.column_name"),
data_type=any_val("c.data_type"),
column_type=any_val("c.COLUMN_TYPE"),
auto_increment=any_val("t.AUTO_INCREMENT"),
is_signed=any_val("locate('unsigned', c.COLUMN_TYPE) = 0"),
)
)
if data is None:
@@ -520,9 +567,9 @@ class nosqlMySQLCtr():
# 查看应用端IP连接数总和
def getConnCount(self, args):
sid = args['sid']
my_instance = self.getInstanceBySid(sid).conn()
if my_instance is False:
return mw.returnData(False,'无法链接')
my_instance, err = self._connect(sid)
if err:
return err
data = my_instance.query(
"SELECT user,db,substring_index(HOST,':',1) AS Client_IP,count(1) AS count FROM information_schema.PROCESSLIST "
@@ -544,9 +591,9 @@ class nosqlMySQLCtr():
# 快速找出没有主键的表
def getFpkInfo(self, args):
sid = args['sid']
my_instance = self.getInstanceBySid(sid).conn()
if my_instance is False:
return mw.returnData(False,'无法链接')
my_instance, err = self._connect(sid)
if err:
return err
data = my_instance.query(
"""
@@ -566,9 +613,9 @@ class nosqlMySQLCtr():
def getLockSql(self, args):
sid = args['sid']
my_instance = self.getInstanceBySid(sid).conn()
if my_instance is False:
return mw.returnData(False,'无法链接')
my_instance, err = self._connect(sid)
if err:
return err
data = my_instance.query(
"""
@@ -597,9 +644,9 @@ class nosqlMySQLCtr():
def killLockPid(self, args):
sid = args['sid']
my_instance = self.getInstanceBySid(sid).conn()
if my_instance is False:
return mw.returnData(False,'无法链接')
my_instance, err = self._connect(sid)
if err:
return err
pid = args['pid']
my_instance.execute('kill %s' % pid)
@@ -607,9 +654,9 @@ class nosqlMySQLCtr():
def killAllLock(self, args):
sid = args['sid']
my_instance = self.getInstanceBySid(sid).conn()
if my_instance is False:
return mw.returnData(False,'无法链接')
my_instance, err = self._connect(sid)
if err:
return err
data = self.getLockSql(args)
if data['status']:
@@ -624,9 +671,9 @@ class nosqlMySQLCtr():
def getDeadlockInfo(self, args):
sid = args['sid']
my_instance = self.getInstanceBySid(sid).conn()
if my_instance is False:
return mw.returnData(False,'无法链接')
my_instance, err = self._connect(sid)
if err:
return err
data = my_instance.find("SHOW ENGINE INNODB STATUS")
if data is not None:
@@ -639,9 +686,9 @@ class nosqlMySQLCtr():
def getSlaveStatus(self, args):
sid = args['sid']
my_instance = self.getInstanceBySid(sid).conn()
if my_instance is False:
return mw.returnData(False,'无法链接')
my_instance, err = self._connect(sid)
if err:
return err
# MySQL 8.0.22+ 使用 SHOW REPLICA STATUS,MySQL 9.0 已移除 SHOW SLAVE STATUS
slave_data = my_instance.query('SHOW REPLICA STATUS')

View File

@@ -0,0 +1,825 @@
# coding:utf-8
import sys
import os
import re
import json
import time
import psycopg2
import psycopg2.extras
web_dir = os.getcwd() + "/web"
if os.path.exists(web_dir):
sys.path.append(web_dir)
os.chdir(web_dir)
import core.mw as mw
PG_SYSTEM_SCHEMAS = ('pg_catalog', 'information_schema', 'pg_toast')
def getPluginName():
return 'postgresql'
def getServerDir():
return mw.getServerDir() + '/' + getPluginName()
def getConf():
return getServerDir() + '/data/postgresql.conf'
def isInstalled():
return os.path.exists(getConf())
def getPort():
content = mw.readFile(getConf())
if content:
tmp = re.search(r'^[#\s]*port\s*=\s*(\d+)', content, re.M)
if tmp:
return int(tmp.groups()[0])
return 5432
def getSocketDir():
sock_name = '.s.PGSQL.' + str(getPort())
for sock_dir in ['/tmp', getServerDir()]:
if os.path.exists(sock_dir + '/' + sock_name):
return sock_dir
return ''
def quoteIdent(name):
return '"' + str(name).replace('"', '""') + '"'
def quoteTable(name):
return '.'.join(quoteIdent(x) for x in str(name).split('.'))
def fmtValue(value):
if value is None:
return None
if isinstance(value, (dict, list, tuple)):
return json.dumps(value, ensure_ascii=False, default=str)
if isinstance(value, (bytes, bytearray, memoryview)):
return bytes(value).hex()
if isinstance(value, (int, float, str, bool)):
return value
return str(value)
def fmtRows(rows):
ret = []
for row in rows:
item = {}
for k in row:
item[k] = fmtValue(row[k])
ret.append(item)
return ret
class PgClient:
def __init__(self, database='postgres'):
self.database = database
self.status = None
self.error = None
self.conn = None
def connect(self):
if not isInstalled():
self.status = 'not_installed'
return False
try:
host = getSocketDir()
if host == '':
host = '127.0.0.1'
self.conn = psycopg2.connect(database=self.database,
user='postgres',
host=host,
port=getPort(),
connect_timeout=3)
self.conn.autocommit = True
return True
except psycopg2.OperationalError as e:
msg = str(e).strip()
if 'does not exist' in msg:
self.status = 'db_not_found'
elif 'authentication' in msg or 'password' in msg:
self.status = 'auth_error'
else:
self.status = 'not_running'
self.error = msg
except Exception as e:
self.status = 'not_running'
self.error = str(e)
return False
def query(self, sql, params=()):
cur = self.conn.cursor(cursor_factory=psycopg2.extras.RealDictCursor)
try:
# 无参数时不能传空 tuple,否则 SQL 里的 % 会被当作占位符
if params:
cur.execute(sql, params)
else:
cur.execute(sql)
rows = cur.fetchall()
return [dict(x) for x in rows]
finally:
cur.close()
def one(self, sql, params=()):
rows = self.query(sql, params)
if len(rows) == 0:
return None
return rows[0]
def execute(self, sql, params=()):
cur = self.conn.cursor()
try:
if params:
cur.execute(sql, params)
else:
cur.execute(sql)
return cur.rowcount
finally:
cur.close()
def close(self):
if self.conn:
self.conn.close()
self.conn = None
def openClient(args, database='postgres'):
client = PgClient(database)
if client.connect():
return client, None
if client.status == 'not_installed':
msg = '未安装'
elif client.status == 'not_running':
msg = '未启动'
elif client.status == 'db_not_found':
msg = '数据库不存在'
elif client.status == 'auth_error':
msg = '连接失败,请检查数据库认证配置'
else:
msg = client.error or '连接失败'
return None, mw.returnData(False, msg)
# 服务器列表
def get_server_list(args):
data = []
if isInstalled():
data.append({'name': '本地服务器', 'val': 'postgresql'})
return mw.returnData(True, 'ok', data)
# 数据库列表
def get_db_list(args):
client, err = openClient(args)
if err:
return err
try:
rows = client.query("select datname from pg_database where datistemplate = false order by datname")
result = {'list': [x['datname'] for x in rows]}
return mw.returnData(True, 'ok', result)
finally:
client.close()
# 数据表列表
def get_table_list(args):
db = args.get('db', '')
client, err = openClient(args, db)
if err:
return err
try:
sql = """
select n.nspname as schemaname, c.relname as tablename
from pg_class c
join pg_namespace n on n.oid = c.relnamespace
where c.relkind in ('r', 'p', 'v', 'm', 'f')
and n.nspname not in ('pg_catalog', 'information_schema', 'pg_toast')
and n.nspname not like 'pg_temp%'
order by n.nspname, c.relname
"""
rows = client.query(sql)
table_list = []
for x in rows:
if x['schemaname'] == 'public':
table_list.append(x['tablename'])
else:
table_list.append(x['schemaname'] + '.' + x['tablename'])
result = {'list': table_list}
return mw.returnData(True, 'ok', result)
finally:
client.close()
# 数据列表
def get_data_list(args):
db = args.get('db', '')
table = args.get('table', '')
p = 1
size = 10
if 'p' in args:
p = int(args['p'])
if 'size' in args:
size = int(args['size'])
start_index = (p - 1) * size
if table == '':
page_args = {}
page_args['count'] = 0
page_args['tojs'] = 'pgGetDataList'
page_args['p'] = 1
page_args['row'] = size
rdata = {}
rdata['page'] = mw.getPage(page_args)
rdata['list'] = []
rdata['count'] = 0
return mw.returnData(True, 'ok', rdata)
where_sql = ''
where_params = []
args_where = {}
if 'where' in args and isinstance(args['where'], dict):
args_where = args['where']
field = args_where.get('field', '')
if field and field != '0':
field_sql = quoteIdent(field)
value = str(args_where.get('value', ''))
if 'id' in field.lower():
where_sql = ' where ' + field_sql + ' = %s'
where_params.append(value)
else:
where_sql = ' where ' + field_sql + ' like %s'
where_params.append('%' + value + '%')
client, err = openClient(args, db)
if err:
return err
try:
try:
sql = 'select count(*) as num from ' + quoteTable(table) + where_sql
count_row = client.one(sql, tuple(where_params))
count = int(count_row['num'])
sql = 'select * from ' + quoteTable(table) + where_sql + ' limit %s offset %s'
params = tuple(where_params) + (size, start_index)
rows = client.query(sql, params)
rows = fmtRows(rows)
except psycopg2.errors.UndefinedTable:
return mw.returnData(False, '数据表不存在:' + table)
except psycopg2.errors.UndefinedColumn:
return mw.returnData(False, '字段不存在,请刷新后重试')
except psycopg2.Error as e:
return mw.returnData(False, '查询失败:' + str(e).strip())
page_args = {}
page_args['count'] = count
page_args['tojs'] = 'pgGetDataList'
page_args['p'] = p
page_args['row'] = size
rdata = {}
rdata['page'] = mw.getPage(page_args)
rdata['list'] = rows
rdata['count'] = count
rdata['soso_field'] = ''
if field and field != '0':
rdata['soso_field'] = field
return mw.returnData(True, 'ok', rdata)
finally:
client.close()
# 进程列表
def get_proccess_list(args):
client, err = openClient(args)
if err:
return err
try:
sql = """
select pid, usename as "user", datname as db,
coalesce(host(client_addr), '本地') as host,
application_name as command, state, query as info,
backend_start, xact_start, query_start,
wait_event_type, wait_event
from pg_stat_activity
where pid <> pg_backend_pid()
and backend_type = 'client backend'
order by pid
"""
rows = fmtRows(client.query(sql))
result = {'list': rows}
return mw.returnData(True, 'ok', result)
finally:
client.close()
# 状态列表
def get_status_list(args):
client, err = openClient(args)
if err:
return err
try:
sql = """
select name, setting, coalesce(unit, '') as unit,
category, short_desc
from pg_settings
order by name
"""
rows = fmtRows(client.query(sql))
result = {'list': rows}
return mw.returnData(True, 'ok', result)
finally:
client.close()
# 统计列表
def get_stats_list(args):
client, err = openClient(args)
if err:
return err
try:
sql = """
select datname as db,
numbackends as conn,
xact_commit as commit, xact_rollback as rollback,
blks_read, blks_hit,
tup_returned, tup_fetched, tup_inserted, tup_updated, tup_deleted,
deadlocks, conflicts, temp_files, temp_bytes,
round(100.0 * blks_hit / nullif(blks_hit + blks_read, 0), 2) as cache_hit_ratio
from pg_stat_database
where datname is not null
order by datname
"""
rows = fmtRows(client.query(sql))
result = {'list': rows}
return mw.returnData(True, 'ok', result)
finally:
client.close()
def _dbStatSnapshot(client):
sql = """
select coalesce(sum(tup_fetched), 0) as fetched,
coalesce(sum(tup_inserted), 0) as inserted,
coalesce(sum(tup_updated), 0) as updated,
coalesce(sum(tup_deleted), 0) as deleted,
coalesce(sum(xact_commit), 0) as commits
from pg_stat_database
"""
row = client.one(sql)
return {
'fetched': int(row['fetched']),
'inserted': int(row['inserted']),
'updated': int(row['updated']),
'deleted': int(row['deleted']),
'commits': int(row['commits']),
}
# QPS/TPS 指标
def get_net_list(args):
from datetime import datetime
client, err = openClient(args)
if err:
return err
try:
row1 = _dbStatSnapshot(client)
time.sleep(1)
row2 = _dbStatSnapshot(client)
max_conn = client.one("select setting from pg_settings where name = 'max_connections'")
conn_row = client.one("select count(*) as num from pg_stat_activity where backend_type = 'client backend'")
row = {}
row['current_time'] = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
row['select'] = row2['fetched'] - row1['fetched']
row['insert'] = row2['inserted'] - row1['inserted']
row['update'] = row2['updated'] - row1['updated']
row['delete'] = row2['deleted'] - row1['deleted']
row['conn'] = conn_row['num']
row['max_conn'] = max_conn['setting']
# PostgreSQL 的 pg_stat 不提供网络字节计数器
row['recv_mbps'] = '-'
row['send_mbps'] = '-'
rdata = []
rdata.append(row)
return mw.returnData(True, 'ok', rdata)
finally:
client.close()
# 查询执行次数最频繁的前N条SQL语句
def get_topn_list(args):
client, err = openClient(args)
if err:
return err
try:
avail = client.one("""
select default_version, installed_version
from pg_available_extensions
where name = 'pg_stat_statements'
""")
if avail is None:
return mw.returnData(False, '当前 PostgreSQL 未提供 pg_stat_statements 扩展(缺少 contrib 模块),无法使用该功能。')
# 先检查 shared_preload_libraries —— pg_stat_statements 必须预加载
preload = client.one("select setting from pg_settings where name = 'shared_preload_libraries'")
libs = (preload or {}).get('setting', '') or ''
if 'pg_stat_statements' not in libs:
return mw.returnData(False, "pg_stat_statements 扩展必须在启动时预加载。\n"
"请在 postgresql.conf 添加 shared_preload_libraries = 'pg_stat_statements' 后重启 PostgreSQL。")
# 再检查扩展是否已 CREATE
ext = client.one("select to_regclass('pg_stat_statements') as v")
if ext is None or ext['v'] is None:
return mw.returnData(False, "pg_stat_statements 扩展已预加载,但尚未启用。\n"
"请在当前数据库执行 CREATE EXTENSION pg_stat_statements;")
version_num = int(client.one('show server_version_num')['server_version_num'])
if version_num >= 130000:
total_col = 'total_exec_time'
max_col = 'max_exec_time'
mean_col = 'mean_exec_time'
else:
total_col = 'total_time'
max_col = 'max_time'
mean_col = 'mean_time'
sql = """
select s.query,
coalesce(d.datname, '-') as db,
'-' as last_seen,
s.calls as exec_count,
round(s.{max_col}::numeric, 2) as max_latency,
round(s.{mean_col}::numeric, 2) as avg_latency
from pg_stat_statements s
left join pg_database d on d.oid = s.dbid
""".format(max_col=max_col, mean_col=mean_col)
filter_db = args.get('filter_db', 'no')
if filter_db == 'yes':
sql += ' where d.datname is not null '
sql += ' order by s.calls desc limit 20'
rows = fmtRows(client.query(sql))
return mw.returnData(True, 'ok', rows)
finally:
client.close()
def _redundantIndexes(client):
sql = """
select n.nspname as table_schema,
t.relname as table_name,
ic.relname as redundant_index_name,
coalesce((
select string_agg(a.attname, ',' order by k.ord)
from unnest(i.indkey) with ordinality as k(attnum, ord)
join pg_attribute a on a.attrelid = i.indrelid and a.attnum = k.attnum
), '') as redundant_index_columns,
'DROP INDEX ' || quote_ident(n.nspname) || '.' || quote_ident(ic.relname) as sql_drop_index
from pg_index i
join pg_class t on t.oid = i.indrelid
join pg_namespace n on n.oid = t.relnamespace
join pg_class ic on ic.oid = i.indexrelid
where n.nspname not in ('pg_catalog', 'information_schema', 'pg_toast')
and not exists (
select 1 from pg_constraint con where con.conindid = i.indexrelid
)
and exists (
select 1
from pg_index i2
join pg_class ic2 on ic2.oid = i2.indexrelid
where i2.indrelid = i.indrelid
and i2.indkey = i.indkey
and i2.indclass = i.indclass
and i2.indcollation = i.indcollation
and i2.indpred is not distinct from i.indpred
and i2.indexprs is not distinct from i.indexprs
and i2.indexrelid <> i.indexrelid
and ic2.relname < ic.relname
)
order by 1, 2, 3
"""
return fmtRows(client.query(sql))
# 查看重复或冗余的索引
def get_redundant_indexes(args):
client, err = openClient(args)
if err:
return err
try:
rows = _redundantIndexes(client)
return mw.returnData(True, 'ok', rows)
finally:
client.close()
# 删除重复或冗余的索引
def redundant_indexes_cmd(args):
client, err = openClient(args)
if err:
return err
try:
rows = _redundantIndexes(client)
index = int(args['index'])
if index >= len(rows):
return mw.returnData(False, '索引不存在,请刷新后重试')
client.execute(rows[index]['sql_drop_index'])
return mw.returnData(True, '执行成功!')
finally:
client.close()
# 统计库里每个表的大小
def get_table_info(args):
client, err = openClient(args)
if err:
return err
try:
sql = """
select n.nspname as "TABLE_SCHEMA",
c.relname as "TABLE_NAME",
case c.relkind
when 'r' then 'table'
when 'p' then 'partitioned table'
when 'v' then 'view'
when 'm' then 'materialized view'
else c.relkind::text
end as "ENGINE",
c.reltuples as rows_estimate,
pg_relation_size(c.oid) as data_bytes,
pg_indexes_size(c.oid) as index_bytes,
pg_total_relation_size(c.oid) as total_bytes,
coalesce((
select string_agg(a.attname, ',' order by k.ord)
from pg_index i
join unnest(i.indkey) with ordinality as k(attnum, ord) on true
join pg_attribute a on a.attrelid = i.indrelid and a.attnum = k.attnum
where i.indrelid = c.oid and i.indisprimary
), '-') as "COLUMN_NAME",
coalesce((
select string_agg(format_type(a.atttypid, a.atttypmod), ',' order by k.ord)
from pg_index i
join unnest(i.indkey) with ordinality as k(attnum, ord) on true
join pg_attribute a on a.attrelid = i.indrelid and a.attnum = k.attnum
where i.indrelid = c.oid and i.indisprimary
), '-') as "COLUMN_TYPE"
from pg_class c
join pg_namespace n on n.oid = c.relnamespace
where c.relkind in ('r', 'p', 'v', 'm')
and n.nspname not in ('pg_catalog', 'information_schema', 'pg_toast')
and n.nspname not like 'pg_temp%'
order by total_bytes desc
"""
rows = client.query(sql)
for i in range(len(rows)):
row = rows[i]
row['DATA_LENGTH'] = round(float(row['data_bytes'] or 0) / 1024 / 1024 / 1024, 2)
row['INDEX_LENGTH'] = round(float(row['index_bytes'] or 0) / 1024 / 1024 / 1024, 2)
row['TOTAL_LENGTH'] = round(float(row['total_bytes'] or 0) / 1024 / 1024 / 1024, 2)
# PostgreSQL 没有 AUTO_INCREMENT,使用 SEQUENCE / IDENTITY
row['AUTO_INCREMENT'] = '-'
row['RESIDUAL_AUTO_INCREMENT'] = '使用 SEQUENCE/IDENTITY'
row['ROWS_ESTIMATE'] = int(row['rows_estimate'] or 0)
del row['data_bytes']
del row['index_bytes']
del row['total_bytes']
return mw.returnData(True, 'ok', fmtRows(rows))
finally:
client.close()
# 查看应用端IP连接数总和
def get_conn_count(args):
client, err = openClient(args)
if err:
return err
try:
sql = """
select usename as "user",
coalesce(datname, '空') as db,
coalesce(host(client_addr), '本地') as "Client_IP",
count(*) as count
from pg_stat_activity
where backend_type = 'client backend'
group by usename, datname, client_addr
order by count desc
"""
rows = fmtRows(client.query(sql))
return mw.returnData(True, 'ok', rows)
finally:
client.close()
# 快速找出没有主键的表
def get_fpk_info(args):
client, err = openClient(args)
if err:
return err
try:
sql = """
select n.nspname as table_schema, c.relname as table_name
from pg_class c
join pg_namespace n on n.oid = c.relnamespace
where c.relkind in ('r', 'p')
and n.nspname not in ('pg_catalog', 'information_schema', 'pg_toast')
and not exists (
select 1 from pg_index i
where i.indrelid = c.oid and i.indisprimary
)
order by n.nspname, c.relname
"""
rows = fmtRows(client.query(sql))
return mw.returnData(True, 'ok', rows)
finally:
client.close()
# 查看当前锁阻塞的SQL
def get_lock_sql(args):
client, err = openClient(args)
if err:
return err
try:
sql = """
select coalesce(a.backend_xid::text, '-') as trx_id,
'等待锁' as trx_state,
a.xact_start as trx_started,
a.pid as processlist_id,
a.query as info,
a.usename as "user",
coalesce(host(a.client_addr), '本地') as host,
a.datname as db,
coalesce(a.wait_event_type, '-') as command,
a.state,
'SELECT pg_cancel_backend(' || a.pid || ')' as sql_kill_blocking_query,
pg_blocking_pids(a.pid) as blocking_pids
from pg_stat_activity a
where cardinality(pg_blocking_pids(a.pid)) > 0
and a.backend_type = 'client backend'
order by a.xact_start
"""
rows = fmtRows(client.query(sql))
return mw.returnData(True, 'ok', rows)
finally:
client.close()
# 终止阻塞会话
def kill_lock_pid(args):
client, err = openClient(args)
if err:
return err
try:
pid = int(args['pid'])
data = client.one('select pg_terminate_backend(%s) as ok', (pid,))
if data is None or data['ok'] is not True:
return mw.returnData(False, '结束会话失败,请检查会话是否存在')
return mw.returnData(True, '执行成功!')
finally:
client.close()
# 终止所有阻塞会话
def kill_all_lock(args):
client, err = openClient(args)
if err:
return err
try:
sql = """
select distinct unnest(pg_blocking_pids(pid)) as pid
from pg_stat_activity
where cardinality(pg_blocking_pids(pid)) > 0
and backend_type = 'client backend'
"""
rows = client.query(sql)
count = 0
for x in rows:
data = client.one('select pg_terminate_backend(%s) as ok', (x['pid'],))
if data is not None and data['ok'] is True:
count += 1
return mw.returnData(True, '执行成功,已结束 %s 个阻塞会话' % count)
finally:
client.close()
# 查看死锁信息
def get_deadlock_info(args):
client, err = openClient(args)
if err:
return err
try:
deadlocks = client.one('select coalesce(sum(deadlocks), 0) as num from pg_stat_database')
locks = client.query("""
select pid, usename as "user", datname as db, state,
coalesce(wait_event_type, '-') as wait_event_type,
query
from pg_stat_activity
where cardinality(pg_blocking_pids(pid)) > 0
and backend_type = 'client backend'
""")
msg = 'PostgreSQL 不保存历史死锁明细,仅提供累计次数与当前锁等待。\n'
msg += '数据库累计死锁次数:%s\n' % deadlocks['num']
if len(locks) == 0:
msg += '当前没有处于锁等待的会话。'
else:
msg += '当前锁等待会话:\n'
for x in locks:
msg += 'pid=%s user=%s db=%s state=%s wait=%s\nquery=%s\n' % (
x['pid'], x['user'], x['db'], x['state'], x['wait_event_type'], x['query'])
return mw.returnData(True, 'ok', msg)
finally:
client.close()
# 查看主从复制信息
def get_slave_status(args):
client, err = openClient(args)
if err:
return err
try:
recovery = client.one('select pg_is_in_recovery() as recovery')['recovery']
if recovery is False:
reps = client.query("""
select client_addr, application_name, state, sync_state,
sent_lsn, write_lsn, flush_lsn, replay_lsn,
coalesce(replay_lag::text, '-') as replay_lag
from pg_stat_replication
""")
if len(reps) == 0:
return mw.returnData(True, 'ok', '未开启主从复制:当前为主库,且没有复制的从库连接。')
msg = '当前为主库,从库复制状态:\n'
for x in reps:
msg += '从库地址:%s 应用:%s\n' % (x['client_addr'], x['application_name'])
msg += '状态:%s 同步模式:%s\n' % (x['state'], x['sync_state'])
msg += 'sent_lsn=%s write_lsn=%s flush_lsn=%s replay_lsn=%s\n' % (
x['sent_lsn'], x['write_lsn'], x['flush_lsn'], x['replay_lsn'])
msg += 'replay_lag=%s\n\n' % x['replay_lag']
return mw.returnData(True, 'ok', msg)
# 当前为从库
lag = client.one("""
select coalesce(extract(epoch from (now() - pg_last_xact_replay_timestamp()))::int, 0) as lag
""")
lsn = client.one("""
select pg_last_wal_receive_lsn() as receive_lsn,
pg_last_wal_replay_lsn() as replay_lsn,
pg_last_xact_replay_timestamp() as replay_time
""")
msg = '当前为从库,复制状态:\n'
msg += 'receive_lsn=%s\n' % lsn['receive_lsn']
msg += 'replay_lsn=%s\n' % lsn['replay_lsn']
msg += '最近回放时间=%s\n' % lsn['replay_time']
msg += '延迟时间:%s 秒' % lag['lag']
return mw.returnData(True, 'ok', msg)
finally:
client.close()

View File

@@ -6,6 +6,7 @@
<div class="tabs-item" data-name="mongodb">Mongodb</div>
<div class="tabs-item" data-name="memcached">Memcached</div>
<div class="tabs-item" data-name="mysql">MySQL</div>
<div class="tabs-item" data-name="postgresql">PostgreSQL</div>
</div>
</div>
@@ -16,6 +17,99 @@
<div class="prompt_description">当前未安装本地服务器,<a class="btlink install_server" href="/soft/index">点击安装</a></div>
</div>
<!-- postgresql start -->
<div class="tab-con hide" id="postgresql" style="padding: 0px;">
<div class="col-md-12" style="padding: 0px;overflow: hidden;">
<div class="tootls_group tootls_top">
<div class="pull-left">
<div class="pgserver_list" style="float:left;">
<select name="sid" class="bt-input-text c5 mr5">
<option value="0">本地服务器</option>
</select>
</div>
<div class="postgresql_db_list" style="float:left;">
<select name="postgresql_db" class="bt-input-text c5 mr5">
<option value="0">数据库空</option>
</select>
</div>
<div class="postgresql_table_list" style="float:left;">
<select name="postgresql_table" class="bt-input-text c5 mr5">
<option value="0">数据表空</option>
</select>
</div>
<div class="field" style="float:left;">
<select name="postgresql_field_key" class="bt-input-text c5 mr5" style="width:80px;">
<option value="0">无字段</option>
</select>
</div>
<div class="value" style="float:left;">
<input name="postgresql_field_value" type="text" class="bt-input-text" placeholder="请输入查找内容">
</div>
<div style="float:left;">
<button id="postgresql_find" type="button" class="btn btn-success btn-sm mr5 ml5" >查找</button>
<button id="postgresql_common" type="button" class="btn btn-success btn-sm mr5 ml5">常用功能</button>
</div>
</div>
</div>
<div style="position: relative;">
<div id="postgresql_table" class="postgresql_table divtable mtb10">
<table class="table table-hover">
<thead style="position: relative;z-index: 1;">
<tr>
<th><span>编号</span></th>
<th><span>操作类型</span></th>
<th><span>详情</span></th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
</div>
<div class="postgresql_list_page page">
<div><span class="Pcurrent">0</span><span class="Pcount">共0条</span></div>
</div>
</div>
<hr style="border:none;" />
<div class="col-md-12" style="padding-left: 3px;">
<div id="postgresql_list_tab" style="padding-top:0px;">
<div class="tab-nav">
<span data-name="proccess" class="on">进程</span>
<span data-name="status" class="">状态</span>
<span data-name="stats" class="">统计</span>
</div>
</div>
<div style="position: relative;">
<div id="postgresql_ot_table" class="divtable">
<table class="table table-hover">
<thead style="position: relative;z-index: 1;">
<tr>
<th><span>编号</span></th>
<th><span>操作类型</span></th>
<th><span>详情</span></th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
</div>
</div>
</div>
<!-- postgresql end -->
<!-- mysql start -->
<!-- show w-full -->
<div class="tab-con hide" id="mysql" style="padding: 0px;">

View File

@@ -143,6 +143,60 @@ function myPostCBN(method, args, callback){
},'json');
}
function pgPostCB(method, args, callback){
var loadT = layer.msg('正在获取...', { icon: 16, time: 0, shade: 0.3 });
var req_data = {};
req_data['name'] = 'data_query';
req_data['func'] = method;
req_data['script']='sql_postgresql';
args['version'] = '';
if (typeof(args) == 'string' && args == ''){
req_data['args'] = JSON.stringify(toArrayObject(args));
} else {
req_data['args'] = JSON.stringify(args);
}
$.post('/plugins/callback', req_data, function(data) {
layer.close(loadT);
if (!data.status){
layer.msg(data.msg,{icon:0,time:2000,shade: [0.3, '#000']});
return;
}
if(typeof(callback) == 'function'){
callback(data);
}
},'json');
}
function pgPostCBN(method, args, callback){
var req_data = {};
req_data['name'] = 'data_query';
req_data['func'] = method;
req_data['script']='sql_postgresql';
args['version'] = '';
if (typeof(args) == 'string' && args == ''){
req_data['args'] = JSON.stringify(toArrayObject(args));
} else {
req_data['args'] = JSON.stringify(args);
}
$.post('/plugins/callback', req_data, function(data) {
if (!data.status){
layer.msg(data.msg,{icon:0,time:2000,shade: [0.3, '#000']});
return;
}
if(typeof(callback) == 'function'){
callback(data);
}
},'json');
}
function selectTab(tab = 'redis'){
$('.tab-view-box .tab-con').addClass('hide').removeClass('show').removeClass('w-full');
@@ -163,6 +217,7 @@ function initTabFunc(tab){
case 'mongodb':initTabMongodb();break;
case 'memcached':initTabMemcached();break;
case 'mysql':initTabMySQL();break;
case 'postgresql':initTabPostgresql();break;
case 'default:':initTabRedis();break;
}
}
@@ -237,7 +292,7 @@ function initTabMemcached(){
$('#memcached_clear_all').unbind('click').click(function(){
var sid = memcachedGetSid();
memPostCB('clear',{'sid':sid} ,function(rdata){
// console.log(rdata);
console.log("xxx",rdata);
showMsg(rdata.data.msg,function(){
if (rdata.data.status){
memcachedGetList();
@@ -927,6 +982,7 @@ function mysqlInitField(f, data){
function mysqlGetServerList(call_func){
closeInstallLayer();
myPostCBN('get_server_list', {}, function(rdata){
var rdata = rdata.data;
if (rdata.data.length != 0){
@@ -951,7 +1007,10 @@ function mysqlGetServerList(call_func){
}
closeInstallLayer();
} else {
showInstallLayer();
layer.msg(rdata.data.msg,{ icon: 7, time: 2000, shade: 0.3 });
setTimeout(function(){
showInstallLayer();
},2050);
}
});
}
@@ -1201,9 +1260,9 @@ function memcachedGetItem(){
function memcachedGetList(){
var sid = memcachedGetSid();
closeInstallLayer();
memPostCB('get_items',{'sid':sid} ,function(rdata){
if (rdata.data.status){
var items = rdata.data.data['items'];
var content = '';
for (var i = 0; i < items.length; i++) {
@@ -1219,10 +1278,14 @@ function memcachedGetList(){
memcachedGetKeyList(1);
});
closeInstallLayer();
memcachedGetKeyList(1);
} else {
showInstallLayer();
layer.msg(rdata.data.msg,{ icon: 7, time: 2000, shade: 0.3 });
setTimeout(function(){
showInstallLayer();
},2050);
}
memcachedGetKeyList(1);
});
}
@@ -1386,7 +1449,6 @@ function mongodbInitField(f, data){
var mogodb_db_list;
function mongodbCollectionName(){
// console.log(mogodb_db_list);
var v = mogodb_db_list.getValue('value');
if (v.length == 0){
// console.log($('#mongodb').data('collection'));
@@ -1397,6 +1459,7 @@ function mongodbCollectionName(){
function mongodbGetList(){
var sid = mongodbGetSid();
closeInstallLayer();
mgdbPostCB('get_db_list',{'sid':sid} ,function(rdata){
// console.log(rdata);
if (rdata.data.status){
@@ -1423,7 +1486,11 @@ function mongodbGetList(){
closeInstallLayer();
} else {
showInstallLayer();
layer.msg(rdata.data.msg,{ icon: 7, time: 2000, shade: 0.3 });
setTimeout(function(){
showInstallLayer();
},2050);
}
});
}
@@ -1606,6 +1673,7 @@ function redisGetIdx(){
function redisGetList(){
var sid = redisGetSid();
closeInstallLayer();
redisPostCB('get_list',{'sid':sid} ,function(rdata){
if (rdata.data.status){
var list = rdata.data.data;
@@ -1627,7 +1695,10 @@ function redisGetList(){
redisGetKeyList(1);
closeInstallLayer();
} else {
showInstallLayer();
layer.msg(rdata.data.msg,{ icon: 7, time: 1000, shade: 0.3 });
setTimeout(function(){
showInstallLayer();
},1050);
}
});
}
@@ -1936,3 +2007,663 @@ function redisBatchClear(){
}
// ------------------------- redis end ---------------------------------
// ------------------------- postgresql start -------------------------------
var pg_timer = null;
var pg_last_error = '';
function pgToastError(msg){
// 轮询失败时避免每 2 秒重复弹出相同的提示
if (!msg || pg_last_error == msg){
return;
}
pg_last_error = msg;
layer.msg(msg,{icon:7,time:2500});
}
function pgHtml(v){
if (v === null || v === undefined){
return '';
}
return String(v).replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/"/g,'&quot;');
}
function pgGetSid(){
return $('#postgresql select[name=sid]').val();
}
function pgGetDbName(){
return $('#postgresql .postgresql_db_list select[name=postgresql_db]').val();
}
function pgGetTableName(){
var table = $('#postgresql .postgresql_table_list select[name=postgresql_table]').val();
if (!table || table == '0'){
return '';
}
return table;
}
function pgShowNotice(title, msg){
layer.open({
type: 1,
title: title,
area: ['560px', '260px'],
closeBtn: 1,
shadeClose: false,
content: '<div class="bt-form pd20"><pre style="white-space:pre-wrap;word-break:break-all;margin:0;line-height:1.8;">'+pgHtml(msg)+'</pre></div>'
});
}
function pgModalTable(title, list, width, height){
if (!list || list.length == 0){
layer.msg('暂无数据',{icon:7});
return;
}
var fields = mongodbGetDataFields(list);
var thead = '';
for (var i = 0; i < fields.length; i++){
thead += '<th>'+pgHtml(fields[i])+'</th>';
}
var tbody = '';
for (var i = 0; i < list.length; i++){
tbody += '<tr>';
for (var j = 0; j < fields.length; j++){
var f = fields[j];
var val = (f in list[i]) ? list[i][f] : '';
tbody += '<td title="'+pgHtml(val)+'">'+pgHtml(val)+'</td>';
}
tbody += '</tr>';
}
layer.open({
type: 1,
title: title,
area: [width || '900px', height || '420px'],
closeBtn: 1,
shadeClose: false,
content: '<div class="bt-form pd20 divtable taskdivtable" style="height:'+(parseInt(height || '420') - 80)+'px;overflow:auto;">\
<table class="table table-hover">\
<thead><tr>'+thead+'</tr></thead>\
<tbody>'+tbody+'</tbody>\
</table>\
</div>'
});
}
function pgInitField(f, data){
var option_html = '<option value="0">无字段</option>';
for (var i = 0; i < f.length; i++){
if (data['soso_field'] == f[i]){
option_html += '<option value="'+pgHtml(f[i])+'" selected>'+pgHtml(f[i])+'</option>';
} else {
option_html += '<option value="'+pgHtml(f[i])+'">'+pgHtml(f[i])+'</option>';
}
}
$('#postgresql select[name="postgresql_field_key"]').html(option_html);
}
function initTabPostgresql(){
clearInterval(pg_timer);
pg_last_error = '';
pgGetServerList(function(){
pgGetDbList();
pgProcessList();
clearInterval(pg_timer);
pg_timer = setInterval(function(){
var name = $('#postgresql_list_tab .tab-nav span.on').data('name');
pgRunPgTab(name);
var fname = $('#cutTab .tabs-item.active').data('name');
if (fname != 'postgresql'){
clearInterval(pg_timer);
}
}, 2000);
});
$('#postgresql_list_tab .tab-nav span').unbind('click').click(function(){
$('#postgresql_list_tab .tab-nav span').removeClass('on');
$(this).addClass('on');
var name = $(this).data('name');
pgRunPgTab(name);
});
$('#postgresql_find').unbind('click').click(function(){
var val = $('#postgresql input[name="postgresql_field_value"]').val();
if (val == ''){
layer.msg('搜索不能为空!',{icon:7});
return;
}
pgGetDataList(1);
});
pgCommonFunc();
}
function pgRunPgTab(name){
switch(name){
case 'proccess':pgProcessList();break;
case 'status':pgStatusList();break;
case 'stats':pgStatsList();break;
}
}
function pgGetServerList(call_func){
closeInstallLayer();
pgPostCBN('get_server_list', {}, function(rdata){
var data = rdata.data;
if (data.data && data.data.length != 0){
var items = data.data;
var content = '';
for (var i = 0; i < items.length; i++){
var t = items[i];
if (i == 0){
content += '<option value="'+t['val']+'" selected>'+t['name']+'</option>';
} else {
content += '<option value="'+t['val']+'">'+t['name']+'</option>';
}
}
$('#postgresql select[name=sid]').html(content);
$('#postgresql select[name=sid]').change(function(){
pgGetDbList();
});
if (typeof(call_func) == 'function'){
call_func();
}
closeInstallLayer();
} else {
layer.msg('当前未安装 PostgreSQL',{icon:7,time:2000,shade:0.3});
setTimeout(function(){
showInstallLayer();
},2050);
}
});
}
function pgGetDbList(){
var sid = pgGetSid();
pgPostCBN('get_db_list',{'sid':sid}, function(rdata){
var data = rdata.data;
if (!data.status){
layer.msg(data.msg,{icon:7,time:2500});
return;
}
var items = data.data['list'];
if (items.length == 0){
$('#postgresql .postgresql_db_list select[name=postgresql_db]').html('<option value="0">数据库空</option>');
$('#postgresql .postgresql_table_list select[name=postgresql_table]').html('<option value="0">数据表空</option>');
$('#postgresql_table thead tr').html('');
$('#postgresql_table tbody').html('');
$('.postgresql_list_page').html('<div><span class="Pcurrent">0</span><span class="Pcount">共0条</span></div>');
return;
}
var content = '';
for (var i = 0; i < items.length; i++){
var name = items[i];
if (i == 0){
content += '<option value="'+pgHtml(name)+'" selected>database['+pgHtml(name)+']</option>';
} else {
content += '<option value="'+pgHtml(name)+'">database['+pgHtml(name)+']</option>';
}
}
$('#postgresql .postgresql_db_list select[name=postgresql_db]').html(content);
$('#postgresql .postgresql_db_list select[name=postgresql_db]').change(function(){
pgGetTableList(1);
});
pgGetTableList(1);
});
}
function pgGetTableList(p){
var sid = pgGetSid();
var db = pgGetDbName();
if (!db || db == '0'){
return;
}
pgPostCBN('get_table_list',{'sid':sid,'db':db}, function(rdata){
var data = rdata.data;
if (!data.status){
layer.msg(data.msg,{icon:7,time:2500});
return;
}
var items = data.data['list'];
if (items.length == 0){
$('#postgresql .postgresql_table_list select[name=postgresql_table]').html('<option value="0">数据表空</option>');
$('#postgresql_table thead tr').html('');
$('#postgresql_table tbody').html('');
$('.postgresql_list_page').html('<div><span class="Pcurrent">0</span><span class="Pcount">共0条</span></div>');
return;
}
var content = '';
for (var i = 0; i < items.length; i++){
var name = items[i];
if (i == 0){
content += '<option value="'+pgHtml(name)+'" selected>table['+pgHtml(name)+']</option>';
} else {
content += '<option value="'+pgHtml(name)+'">table['+pgHtml(name)+']</option>';
}
}
$('#postgresql .postgresql_table_list select[name=postgresql_table]').html(content);
$('#postgresql .postgresql_table_list select[name=postgresql_table]').change(function(){
pgGetDataList(1);
});
pgGetDataList(1);
});
}
function pgGetDataList(p){
var sid = pgGetSid();
var db = pgGetDbName();
var table = pgGetTableName();
var pg_field = $('#postgresql select[name="postgresql_field_key"]').val();
var pg_value = $('#postgresql input[name="postgresql_field_value"]').val();
var request_data = {
'sid': sid,
'db': db,
'table': table,
'p': p,
'size': 10
};
if (pg_field != '0' && pg_field){
request_data['where'] = {field: pg_field, value: pg_value};
} else {
request_data['where'] = {};
}
pgPostCB('get_data_list', request_data, function(rdata){
var data = rdata.data;
if (!data.status){
layer.msg(data.msg,{icon:7,time:2500});
return;
}
var rdata2 = data.data;
var dlist = rdata2['list'];
var fields = mongodbGetDataFields(dlist);
if (fields.length != 0){
pgInitField(fields, rdata2);
}
var header_field = '';
for (var i = 0; i < fields.length; i++){
header_field += '<th>'+pgHtml(fields[i])+'</th>';
}
$('#postgresql_table thead tr').html(header_field);
var tbody = '';
for (var i = 0; i < dlist.length; i++){
tbody += '<tr>';
for (var j = 0; j < fields.length; j++){
var f = fields[j];
var val = (f in dlist[i]) ? dlist[i][f] : '';
tbody += '<td title="'+pgHtml(val)+'">'+pgHtml(val)+'</td>';
}
tbody += '</tr>';
}
$('#postgresql_table tbody').html(tbody);
$('#postgresql .postgresql_list_page').html(rdata2['page']);
});
}
function pgRenderOtTable(dlist){
var fields = mongodbGetDataFields(dlist);
var header_field = '';
for (var i = 0; i < fields.length; i++){
header_field += '<th>'+pgHtml(fields[i])+'</th>';
}
$('#postgresql_ot_table thead tr').html(header_field);
var tbody = '';
for (var i = 0; i < dlist.length; i++){
tbody += '<tr>';
for (var j = 0; j < fields.length; j++){
var f = fields[j];
var val = (f in dlist[i]) ? dlist[i][f] : '';
tbody += '<td title="'+pgHtml(val)+'">'+pgHtml(val)+'</td>';
}
tbody += '</tr>';
}
$('#postgresql_ot_table tbody').html(tbody);
}
function pgProcessList(){
pgPostCBN('get_proccess_list',{'sid':pgGetSid()}, function(rdata){
var data = rdata.data;
if (!data.status){
pgToastError(data.msg);
return;
}
pg_last_error = '';
pgRenderOtTable(data.data['list']);
});
}
function pgStatusList(){
pgPostCBN('get_status_list',{'sid':pgGetSid()}, function(rdata){
var data = rdata.data;
if (!data.status){
pgToastError(data.msg);
return;
}
pg_last_error = '';
pgRenderOtTable(data.data['list']);
});
}
function pgStatsList(){
pgPostCBN('get_stats_list',{'sid':pgGetSid()}, function(rdata){
var data = rdata.data;
if (!data.status){
pgToastError(data.msg);
return;
}
pg_last_error = '';
pgRenderOtTable(data.data['list']);
});
}
function pgCommonFunc(){
$('#postgresql_common').unbind('click').click(function(){
layer.open({
type: 1,
title: "PostgreSQL常用功能",
area: ['600px', '200px'],
closeBtn: 1,
shadeClose: false,
content: '<div class="bt-form pd20">\
<button style="margin-bottom: 8px;" id="pg_top_nsql" type="button" class="btn btn-default btn-sm">查询执行次数最频繁的前N条SQL语句</button>\
<button style="margin-bottom: 8px;" id="pg_net_stat" type="button" class="btn btn-default btn-sm">PostgreSQL服务器的QPS/TPS指标</button>\
<button style="margin-bottom: 8px;" id="pg_redundant_indexes" type="button" class="btn btn-default btn-sm">查看重复或冗余的索引</button>\
<button style="margin-bottom: 8px;" id="pg_table_info" type="button" class="btn btn-default btn-sm">统计库里每个表的大小</button>\
<button style="margin-bottom: 8px;" id="pg_conn_count" type="button" class="btn btn-default btn-sm">查看应用端IP连接数总和</button>\
<button style="margin-bottom: 8px;" id="pg_fpk_info" type="button" class="btn btn-default btn-sm">快速找出没有主键的表</button>\
<button style="margin-bottom: 8px;" id="pg_lock_sql" type="button" class="btn btn-default btn-sm">查看当前锁阻塞的SQL</button>\
<button style="margin-bottom: 8px;" id="pg_deadlock_info" type="button" class="btn btn-default btn-sm">查看死锁信息</button>\
<button style="margin-bottom: 8px;" id="pg_slave_status" type="button" class="btn btn-default btn-sm">查看主从复制信息</button>\
</div>',
success:function(i,l){
$('#pg_top_nsql').click(function(){ pgCommonFuncTopN(); });
$('#pg_net_stat').click(function(){ pgCommonFuncNet(); });
$('#pg_redundant_indexes').click(function(){ pgCommonFuncRedundantIndexes(); });
$('#pg_table_info').click(function(){ pgCommonFuncTableInfo(); });
$('#pg_conn_count').click(function(){ pgCommonFuncConnCount(); });
$('#pg_fpk_info').click(function(){ pgCommonFuncFpkInfo(); });
$('#pg_lock_sql').click(function(){ pgCommonFuncLockSQL(); });
$('#pg_deadlock_info').click(function(){ pgCommonFuncDeadlockInfo(); });
$('#pg_slave_status').click(function(){ pgCommonFuncSlaveStatus(); });
}
});
});
}
function pgCommonFuncTopN(){
pgPostCBN('get_topn_list',{'sid':pgGetSid()}, function(rdata){
var data = rdata.data;
if (!data.status){
pgShowNotice('查询执行次数最频繁的前N条SQL语句', data.msg);
return;
}
pgModalTable('查询执行次数最频繁的前N条SQL语句', data.data, '1000px', '450px');
});
}
function pgCommonFuncNet(){
pgPostCBN('get_net_list',{'sid':pgGetSid()}, function(rdata){
var data = rdata.data;
if (!data.status){
pgShowNotice('PostgreSQL服务器的QPS/TPS指标', data.msg);
return;
}
pgModalTable('PostgreSQL服务器的QPS/TPS指标(网络带宽需在系统层监控)', data.data, '1000px', '360px');
});
}
function pgCommonFuncRedundantIndexes(){
function renderList(){
pgPostCBN('get_redundant_indexes',{'sid':pgGetSid()}, function(rdata){
var data = rdata.data;
if (!data.status){
layer.msg(data.msg,{icon:7,time:2500});
return;
}
var items = data.data;
if (items.length == 0){
layer.msg('没有发现重复或冗余的索引',{icon:7});
return;
}
var tbody = '';
for (var i = 0; i < items.length; i++){
tbody += '<tr>\
<td>'+pgHtml(items[i]['table_schema'])+'</td>\
<td>'+pgHtml(items[i]['table_name'])+'</td>\
<td>'+pgHtml(items[i]['redundant_index_name'])+'</td>\
<td>'+pgHtml(items[i]['redundant_index_columns'])+'</td>\
<td><a class="pg_drop_index btlink" index="'+i+'">删除</a></td>\
</tr>';
}
layer.open({
type: 1,
title: "查看重复或冗余的索引",
area: ['1000px', '420px'],
closeBtn: 1,
shadeClose: false,
content: '<div class="bt-form pd20 divtable taskdivtable">\
<table class="table table-hover" id="pg_redundant_table">\
<thead><tr>\
<th>库名</th><th>表名</th><th>冗余索引</th><th>字段</th><th>操作</th>\
</tr></thead>\
<tbody>'+tbody+'</tbody>\
</table>\
</div>',
success: function(){
$('#pg_redundant_table .pg_drop_index').click(function(){
var index = $(this).attr('index');
layer.confirm('确定删除索引 '+pgHtml(items[index]['redundant_index_name'])+' ?', {btn:['确定','取消']}, function(li){
pgPostCB('redundant_indexes_cmd', {'sid':pgGetSid(),'index':index}, function(r2){
var d = r2.data;
showMsg(d.msg,function(){
if (d.status){
layer.close(li);
renderList();
}
},{icon: d.status ? 1 : 2}, 2000);
});
});
});
}
});
});
}
renderList();
}
function pgCommonFuncTableInfo(){
pgPostCBN('get_table_info',{'sid':pgGetSid()}, function(rdata){
var data = rdata.data;
if (!data.status){
pgShowNotice('统计库里每个表的大小(单位 GB)', data.msg);
return;
}
pgModalTable('统计库里每个表的大小(单位 GB)', data.data, '1200px', '460px');
});
}
function pgCommonFuncConnCount(){
pgPostCBN('get_conn_count',{'sid':pgGetSid()}, function(rdata){
var data = rdata.data;
if (!data.status){
pgShowNotice('查看应用端IP连接数总和', data.msg);
return;
}
pgModalTable('查看应用端IP连接数总和', data.data, '700px', '420px');
});
}
function pgCommonFuncFpkInfo(){
pgPostCBN('get_fpk_info',{'sid':pgGetSid()}, function(rdata){
var data = rdata.data;
if (!data.status){
layer.msg(data.msg,{icon:7,time:2500});
return;
}
pgModalTable('快速找出没有主键的表', data.data, '800px', '400px');
});
}
function pgCommonFuncLockSQL(){
function renderSQL(){
pgPostCBN('get_lock_sql',{'sid':pgGetSid()}, function(rdata){
var data = rdata.data;
if (!data.status){
layer.msg(data.msg,{icon:7,time:2500});
return;
}
var items = data.data;
var tbody = '';
for (var i = 0; i < items.length; i++){
var t = '<tr>';
t += '<td>'+pgHtml(items[i]['trx_id'])+'</td>';
t += '<td>'+pgHtml(items[i]['trx_state'])+'</td>';
t += '<td>'+pgHtml(items[i]['trx_started'])+'</td>';
t += '<td>'+pgHtml(items[i]['processlist_id'])+'</td>';
t += '<td title="'+pgHtml(items[i]['info'])+'">'+pgHtml(items[i]['info'])+'</td>';
t += '<td>'+pgHtml(items[i]['user'])+'</td>';
t += '<td>'+pgHtml(items[i]['host'])+'</td>';
t += '<td>'+pgHtml(items[i]['db'])+'</td>';
t += '<td>'+pgHtml(items[i]['command'])+'</td>';
t += '<td>'+pgHtml(items[i]['state'])+'</td>';
t += '<td>'+pgHtml(items[i]['sql_kill_blocking_query'])+'</td>';
t += '<td><a class="exec btlink" index="'+i+'">执行</a></td>';
t += '</tr>';
tbody += t;
}
$('#pg_lock_table tbody').html(tbody);
$('#pg_lock_table tbody .exec').click(function(){
var index = $(this).attr('index');
var pid = items[index]['processlist_id'];
pgPostCB('kill_lock_pid', {'sid':pgGetSid(),'pid':pid}, function(r2){
var d = r2.data;
showMsg(d.msg,function(){
if (d.status){
renderSQL();
}
},{icon: d.status ? 1 : 2}, 2000);
});
});
});
}
layer.open({
type: 1,
title: "查看当前锁阻塞的SQL",
area: ['1100px', '420px'],
closeBtn: 1,
shadeClose: false,
content: '<div class="bt-form pd20 divtable taskdivtable">\
<div class="mr20 pull-left" style="border-right: 1px solid #ccc; padding-right: 20px;">\
<button id="pg_kill_all" type="button" class="btn btn-default btn-sm">关闭所有阻塞</button>\
</div>\
<hr />\
<table class="table table-hover" id="pg_lock_table">\
<thead><tr>\
<th>事务ID</th><th>事务状态</th><th>执行时间</th><th>线程ID</th>\
<th>Info</th><th>user</th><th>host</th><th>db</th>\
<th>command</th><th>state</th><th>kill</th><th>操作</th>\
</tr></thead>\
<tbody></tbody>\
</table>\
</div>',
success:function(){
renderSQL();
$('#pg_kill_all').unbind('click').click(function(){
pgPostCB('kill_all_lock', {'sid':pgGetSid()}, function(r2){
var d = r2.data;
showMsg(d.msg,function(){
if (d.status){
renderSQL();
}
},{icon: d.status ? 1 : 2}, 2000);
});
});
}
});
}
function pgCommonFuncDeadlockInfo(){
function renderText(){
pgPostCBN('get_deadlock_info',{'sid':pgGetSid()}, function(rdata){
var data = rdata.data;
if (!data.status){
layer.msg(data.msg,{icon:7,time:2500});
return;
}
$('#pg_info_log').val(data.data);
});
}
layer.open({
type: 1,
title: "查看死锁信息",
area: ['800px', '400px'],
closeBtn: 1,
shadeClose: false,
content: '<div class="bt-form pd15">\
<textarea readonly="" style="margin: 0px;height: 330px;width: 100%;background-color: #333;color:#fff; padding:0 5px" id="pg_info_log"></textarea>\
</div>',
success:function(){
renderText();
}
});
}
function pgCommonFuncSlaveStatus(){
function renderText(){
pgPostCBN('get_slave_status',{'sid':pgGetSid()}, function(rdata){
var data = rdata.data;
if (!data.status){
layer.msg(data.msg,{icon:7,time:2500});
return;
}
$('#pg_info_log').val(data.data);
});
}
layer.open({
type: 1,
title: "查看主从复制信息",
area: ['800px', '400px'],
closeBtn: 1,
shadeClose: false,
content: '<div class="bt-form pd15">\
<textarea readonly="" style="margin: 0px;height: 330px;width: 100%;background-color: #333;color:#fff; padding:0 5px" id="pg_info_log"></textarea>\
</div>',
success:function(){
renderText();
}
});
}
// ------------------------- postgresql end ---------------------------------

View File

@@ -135,9 +135,6 @@ def initDreplace():
return ''
def appOp(method):
initDreplace()
if not mw.isAppleSystem():

View File

@@ -2,7 +2,7 @@
"ps": "DNS over HTTPS(DoH)是一种通过HTTPS协议加密域名解析请求的技术!",
"name": "doh",
"title": "DoH",
"versions": ["0.9.15"],
"versions": ["0.9.15","0.10.0"],
"tip": "soft",
"install_pre_inspection":false,
"uninstall_pre_inspection":true,

View File

@@ -9,9 +9,9 @@ Type=simple
User=www
Group=www
WorkingDirectory={$SERVER_PATH}/doh
# /www/server/doh/doh-proxy -u 127.0.0.1:53 -l 127.0.0.1:3000
# /www/server/doh/doh-proxy -u 127.0.0.1:53 -l 127.0.0.1:3198
# /www/server/doh/doh-proxy -h
ExecStart={$SERVER_PATH}/doh/doh-proxy -u 127.0.0.1:53 -l 127.0.0.1:3000
ExecStart={$SERVER_PATH}/doh/doh-proxy -u 127.0.0.1:53 -l 127.0.0.1:3198
Restart=always
RemainAfterExit=yes
#AmbientCapabilities=CAP_NET_BIND_SERVICE

View File

@@ -59,22 +59,16 @@ Install_App()
if [ -f $serverPath/source/doh/$file_xz ];then
cd $serverPath/source/doh && tar -xjf $file_xz
fi
echo "mv $serverPath/source/doh/doh-proxy $serverPath/doh"
if [ -f $serverPath/source/doh/doh-proxy ];then
echo "mv $serverPath/source/doh/doh-proxy $serverPath/doh"
mv $serverPath/source/doh/doh-proxy $serverPath/doh
fi
if [ -d $serverPath/doh ];then
echo $version > $serverPath/doh/version.pl
cd ${rootPath} && python3 plugins/doh/index.py start
cd ${rootPath} && python3 plugins/doh/index.py initd_install
fi
echo $version > $serverPath/doh/version.pl
echo 'install doh success'
}

View File

@@ -2,7 +2,7 @@
"ps": "Gitea是一个开源社区驱动的轻量级代码托管解决方案。",
"name": "gitea",
"title": "Gitea",
"versions": ["1.17.2","1.18.5","1.22.1","1.24.3"],
"versions": ["1.17.2","1.18.5","1.22.1","1.24.3","1.25.3"],
"tip": "soft",
"install_pre_inspection":false,
"uninstall_pre_inspection":true,

View File

@@ -2,6 +2,11 @@
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
# cd /www/server/mdserver-web/plugins/gitea && bash install.sh upgrade 1.25.3
action=$1
version=$2
curPath=`pwd`
rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
@@ -12,6 +17,7 @@ if [ -f ${rootPath}/bin/activate ];then
fi
URL_DOWNLOAD=https://dl.gitea.com
@@ -87,20 +93,21 @@ Install_App()
chown -R www:www $serverPath/gitea
fi
if [ -d $serverPath/gitea ];then
echo $version > $serverPath/gitea/version.pl
if [ -d $serverPath/gitea ] && [ "${action}" = 'install' ] ;then
cd ${rootPath} && python3 plugins/gitea/index.py start
cd ${rootPath} && python3 plugins/gitea/index.py initd_install
fi
echo $version > $serverPath/gitea/version.pl
echo 'install success'
if [ "$action" = "upgrade" ];then
which systemctl && systemctl restart gitea
fi
}
Uninstall_App()
{
if [ -f /usr/lib/systemd/system/gitea.service ];then
systemctl stop gitea
systemctl disable gitea
@@ -116,11 +123,10 @@ Uninstall_App()
echo 'uninstall success'
}
action=$1
version=$2
if [ "${1}" = 'install' ];then
if [ "${action}" = 'install' ] || [ "$action" = "upgrade" ];then
Install_App $version
else
elif [ "${action}" = 'uninstall' ];then
Uninstall_App $version
else
echo "OPTIONS ERROR"
fi

View File

@@ -3,17 +3,13 @@ indexer {
}
searchd {
listen = 127.0.0.1:9322
listen = 127.0.0.1:9322:sphinx
listen = 127.0.0.1:9326:mysql
listen = 127.0.0.1:9328:http
log = /var/log/manticore/searchd.log
query_log = /var/log/manticore/query.log
pid_file = /var/run/manticore/searchd.pid
data_dir = /var/lib/manticore
workers = threads
binlog_path = /var/lib/manticore
max_children = 1000
max_matches = 1000000
#binlog_path = /var/lib/manticore/binlog
}

View File

@@ -21,6 +21,7 @@
<p onclick="pluginLogs('manticoresearch','','query_log', 30);">查询日志</p>
<p onclick="mcsRunStatus();">运行状态</p>
<p onclick="mcsCommonFunc();">常用功能</p>
<p onclick="pluginLogsContent('manticoresearch',$('.plugin_version').attr('version'),'systemctl_log');">服务运行日志</p>
<p onclick="mcsReadme();">说明</p>
</div>
<div class="bt-w-con pd15">

View File

@@ -141,15 +141,18 @@ def initDreplace():
dirs_list = [
"/var/log/manticore",
"/var/run/manticore",
"/var/lib/manticore"
"/var/lib/manticore",
]
index_dir = getServerDir() + '/index'
dirs_list.append(index_dir)
for d in dirs_list:
if not os.path.exists(d):
mw.execShell('mkdir -p ' + d)
mw.execShell("chown -R manticore:manticore /var/run/manticore")
mw.execShell("chown -R manticore:manticore "+index_dir)
# config replace
conf_bin = getConf()
@@ -205,8 +208,10 @@ def reload():
def rebuild():
fixIndexOwner()
cmd = 'indexer --all --rotate'
data = mw.execShell(cmd)
cmd_manticore = asManticore(cmd)
data = mw.execShell(cmd_manticore)
if data[0].find('successfully')<0:
return data[0].replace("\n","<br/>")
return 'ok'
@@ -273,6 +278,11 @@ def queryLog():
tmp = re.search(rep, content)
return tmp.groups()[0]
def systemctlLog():
cmd = "journalctl -u manticore -n 15 --no-pager"
data = mw.execShell(cmd)
return data[0]
def runStatus():
s = status()
@@ -284,7 +294,7 @@ def runStatus():
sh = sphinxapi.SphinxClient()
port = getMainPort()
sh.SetServer('127.0.0.1', port)
sh.SetServer('127.0.0.1', int(port))
info_status = sh.Status()
if info_status is None:
@@ -320,8 +330,8 @@ def sphinxConfParse():
file = getConf()
bin_dir = getServerDir()
content = mw.readFile(file)
rep = r'index\s(.*)'
sindex = re.findall(rep, content)
rep = r'^index\s+(\w+)'
sindex = re.findall(rep, content,re.MULTILINE)
indexlen = len(sindex)
cmd = {}
cmd['cmd'] = "indexer -c " + getConf()
@@ -413,6 +423,21 @@ def makeDbToSphinx():
return mw.returnJson(True,'测试中')
# 以 manticore 用户执行,避免生成文件属主为 root
def asManticore(cmd):
if mw.isAppleSystem():
return cmd
return 'su -s /bin/sh manticore -c "' + cmd + '"'
# 重建前修正索引目录归属,保证 manticore 用户有写权限
def fixIndexOwner():
index_dir = getServerDir() + '/index'
if not os.path.exists(index_dir):
return
mw.execShell("chown -R manticore:manticore " + index_dir)
# 全量更新
def updateAll():
data = sphinxConfParse()
@@ -421,10 +446,12 @@ def updateAll():
return '无更新'
index = data['index']
fixIndexOwner()
for x in range(len(index)):
cmd_index = cmd + ' ' + index[x]['index'] + ' --rotate'
subprocess.run(asManticore(cmd_index), shell=True)
print(cmd_index)
os.system(cmd_index)
return ''
#增量更新
@@ -435,15 +462,16 @@ def updateDelta():
return '无更新'
index = data['index']
fixIndexOwner()
for x in range(len(index)):
if 'delta' in index[x]:
cmd_index = cmd + ' ' + index[x]['delta'] + ' --rotate'
subprocess.run(asManticore(cmd_index), shell=True)
print(cmd_index)
os.system(cmd_index)
cmd_index_merge = cmd + ' --merge ' + index[x]['index'] + ' ' + index[x]['delta'] + ' --rotate'
subprocess.run(asManticore(cmd_index_merge), shell=True)
print(cmd_index_merge)
os.system(cmd_index_merge)
else:
print(index[x]['index'],'no delta')
@@ -491,6 +519,8 @@ if __name__ == "__main__":
print(runLog())
elif func == 'query_log':
print(queryLog())
elif func == 'systemctl_log':
print(systemctlLog())
elif func == 'run_status':
print(runStatus())
elif func == 'run_status_test':

View File

@@ -4,7 +4,7 @@
"name": "manticoresearch",
"title": "manticoresearch",
"shell": "install.sh",
"versions":["7.4.6"],
"versions":["latest"],
"tip": "soft",
"install_pre_inspection":true,
"checks": "server/manticoresearch",

View File

@@ -9,9 +9,13 @@ serverPath=$(dirname "$rootPath")
sysName=`uname`
sysArch=`arch`
# cd /www/server/mdserver-web/plugins/manticoresearch && bash install.sh install 7.4.6
# cd /www/server/mdserver-web/plugins/manticoresearch && bash install.sh install latest
# cd /www/server/mdserver-web && python3 plugins/manticoresearch/index.py run_status_test
# cd /www/server/mdserver-web && python3 plugins/manticoresearch/index.py start
# su -s /bin/sh manticore -c "indexer -c /etc/manticoresearch/manticore.conf xx --rotate"
# su -s /bin/sh manticore -c "indexer -c /etc/manticoresearch/manticore.conf xx_delta --rotate"
# systemctl status manticore
# systemctl restart manticore

View File

@@ -98,8 +98,8 @@ logs_file=$plugin_path/${rname}.log
''' % (mw_dir, name, getServerDir(), getPluginDir())
cmd += 'echo "★【`date +"%Y-%m-%d %H:%M:%S"`】 STSRT★" >> $logs_file' + "\n"
cmd += 'echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" >> $logs_file' + "\n"
cmd += 'echo "python3 $script_path/index.py update_all"' + "\n"
cmd += 'cd $mw_dir && python3 $script_path/index.py update_all' + "\n"
cmd += 'cd $mw_dir && . bin/activate && python3 plugins/manticoresearch/index.py update_all' + "\n"
cmd += 'echo "cd $mw_dir && . bin/activate && python3 plugins/manticoresearch/index.py update_all"' + "\n"
cmd += 'echo "【`date +"%Y-%m-%d %H:%M:%S"`】 END★" >> $logs_file' + "\n"
cmd += 'echo "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<" >> $logs_file' + "\n"
@@ -147,8 +147,8 @@ logs_file=$plugin_path/${rname}.log
''' % (mw_dir, name, getServerDir(), getPluginDir())
cmd += 'echo "★【`date +"%Y-%m-%d %H:%M:%S"`】 STSRT★" >> $logs_file' + "\n"
cmd += 'echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" >> $logs_file' + "\n"
cmd += 'echo "python3 $script_path/index.py update_delta"' + "\n"
cmd += 'cd $mw_dir && python3 $script_path/index.py update_delta' + "\n"
cmd += 'cd $mw_dir && . bin/activate && python3 plugins/manticoresearch/index.py update_delta' + "\n"
cmd += 'echo "cd $mw_dir && . bin/activate && python3 plugins/manticoresearch/index.py update_delta"' + "\n"
cmd += 'echo "【`date +"%Y-%m-%d %H:%M:%S"`】 END★" >> $logs_file' + "\n"
cmd += 'echo "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<" >> $logs_file' + "\n"

View File

@@ -3,7 +3,7 @@
#
searchd {
listen = 127.0.0.1:9322
listen = 127.0.0.1:9322:sphinx
listen = 127.0.0.1:9326:mysql
listen = 127.0.0.1:9328:http
log = /var/log/manticore/searchd.log

View File

@@ -1,9 +1,8 @@
searchd {
listen = 127.0.0.1:9322
listen = 127.0.0.1:9322:sphinx
listen = 127.0.0.1:9326:mysql
listen = 127.0.0.1:9328:http
log = /var/log/manticore/searchd.log
query_log = /var/log/manticore/query.log
pid_file = /var/run/manticore/searchd.pid
data_dir = /var/lib/manticore
}

View File

@@ -23,21 +23,23 @@ Install_App()
MC_DIR=${serverPath}/source/manticoresearch
mkdir -p $MC_DIR
# wget --no-check-certificate -O /www/server/source/manticoresearch/manticore-repo.noarch.deb https://repo.manticoresearch.com/manticore-repo.noarch.deb
# cd /www/server/source/manticoresearch/ && dpkg -i manticore-repo.noarch.deb
wget --no-check-certificate -O $MC_DIR/manticore-repo.noarch.deb https://repo.manticoresearch.com/manticore-repo.noarch.deb
dpkg -i $MC_DIR/manticore-repo.noarch.deb
apt update -y
apt -y install manticore manticore-extra
apt -y install manticore
apt -y install manticore-extra
apt -y upgrade manticore
echo "${VERSION}" > $serverPath/manticoresearch/version.pl
cd ${rootPath} && python3 plugins/manticoresearch/index.py start ${VERSION}
cd ${rootPath} && python3 plugins/manticoresearch/index.py initd_install ${VERSION}
if [ -d ${MC_DIR} ];then
rm -rf ${MC_DIR}
fi
# if [ -d ${MC_DIR} ];then
# rm -rf ${MC_DIR}
# fi
}
Uninstall_App()
@@ -45,7 +47,8 @@ Uninstall_App()
cd ${rootPath} && python3 plugins/manticoresearch/index.py stop ${VERSION}
cd ${rootPath} && python3 plugins/manticoresearch/index.py initd_uninstall ${VERSION}
apt -y remove manticore manticore-extra
apt -y remove manticore
apt -y remove manticore-extra
apt -y autoremove
if [ -d $serverPath/manticoresearch ];then

View File

@@ -25,7 +25,8 @@ Install_App()
mkdir -p $MC_DIR
yum install -y https://repo.manticoresearch.com/manticore-repo.noarch.rpm
yum install -y manticore manticore-extra
yum install -y manticore
yum install -y manticore-extra
echo "${VERSION}" > $serverPath/manticoresearch/version.pl
@@ -39,7 +40,8 @@ Install_App()
Uninstall_App()
{
yum -y remove manticore manticore-extra
yum -y remove manticore
yum -y remove manticore-extra
if [ -d $serverPath/manticoresearch ];then
rm -rf $serverPath/manticoresearch

View File

@@ -18,6 +18,7 @@ log-error = {$SERVER_APP_PATH}/data/error.log
server-id = {$SERVER_ID}
default_storage_engine = InnoDB
performance_schema = 1
key_buffer_size = 8M
max_allowed_packet = 100M
@@ -71,7 +72,11 @@ replicate-ignore-db = information_schema
replicate-ignore-db = performance_schema
replicate-ignore-db = mysql
replicate-ignore-db = test
replicate-wild-ignore-table=mysql.%
replicate-wild-ignore-table = mysql.%
replicate-wild-ignore-table = information_schema.%
replicate-wild-ignore-table = performance_schema.%
replicate-wild-ignore-table = sys.%
innodb_data_home_dir = {$SERVER_APP_PATH}/data

View File

@@ -626,7 +626,10 @@ def runInfo(version):
return mw.returnJson(False, 'MySQL未启动', [])
db = pMysqlDb()
data = db.query('show global status')
try:
data = db.query('show global status')
except Exception as e:
data = e
isError = isSqlError(data)
if isError != None:
return isError
@@ -659,7 +662,10 @@ def runInfo(version):
def myDbStatus():
result = {}
db = pMysqlDb()
data = db.query('show variables')
try:
data = db.query('show variables')
except Exception as e:
data = e
isError = isSqlError(data)
if isError != None:
return isError
@@ -726,21 +732,33 @@ def isSqlError(mysqlMsg):
def __createUser(dbname, username, password, address):
pdb = pMysqlDb('mysql')
pdb = pMysqlDb()
if username == 'root':
dbname = '*'
try:
pdb.execute("CREATE USER `%s`@`localhost` IDENTIFIED BY '%s'" % (username, password))
except Exception as e:
pass
pdb.execute(
"CREATE USER `%s`@`localhost` IDENTIFIED BY '%s'" % (username, password))
pdb.execute(
"grant all privileges on %s.* to `%s`@`localhost`" % (dbname, username))
try:
pdb.execute("grant all privileges on %s.* to `%s`@`localhost`" % (dbname, username))
except Exception as e:
pass
for a in address.split(','):
pdb.execute(
"CREATE USER `%s`@`%s` IDENTIFIED BY '%s'" % (username, a, password))
pdb.execute(
"grant all privileges on %s.* to `%s`@`%s`" % (dbname, username, a))
pdb.execute("flush privileges")
try:
pdb.execute("CREATE USER `%s`@`%s` IDENTIFIED BY '%s'" % (username, a, password))
except Exception as e:
pass
try:
pdb.execute("grant all privileges on %s.* to `%s`@`%s`" % (dbname, username, a))
except Exception as e:
pass
try:
pdb.execute("flush privileges")
except Exception as e:
pass
def getDbBackupListFunc(dbname=''):
@@ -763,8 +781,8 @@ def setDbBackup():
if not data[0]:
return data[1]
scDir = getPluginDir() + '/scripts/backup.py'
cmd = 'python3 ' + scDir + ' database ' + args['name'] + ' 3'
head = "cd "+mw.getPanelDir()
cmd = head +' && . bin/activate && python3 plugins/mariadb/scripts/backup.py database ' + args['name'] + ' 3'
os.system(cmd)
return mw.returnJson(True, 'ok')
@@ -794,6 +812,49 @@ def importDbBackup():
os.system(mysql_cmd)
return mw.returnJson(True, 'ok')
def importDbBackupProgress():
args = getArgs()
data = checkArgs(args, ['file', 'name'])
if not data[0]:
return data[1]
file = args['file']
name = args['name']
cmd = 'cd '+mw.getServerDir()+'/mdserver-web && . bin/activate && '
cmd += 'python3 '+mw.getServerDir()+'/mdserver-web/plugins/mariadb/index.py import_db_backup_progress_bar {"file":"'+file+'","name":"'+name+'"}'
return mw.returnJson(True, 'ok',cmd)
def importDbBackupProgressBar():
args = getArgs()
data = checkArgs(args, ['file', 'name'])
if not data[0]:
return data[1]
file = args['file']
name = args['name']
file_path = mw.getFatherDir() + '/backup/database/mariadb/' + file
file_path_sql = mw.getFatherDir() + '/backup/database/mariadb/' + file.replace('.gz', '')
if not os.path.exists(file_path_sql):
cmd = 'cd ' + mw.getFatherDir() + '/backup/database/mariadb && gzip -dk ' + file
mw.execShell(cmd)
local_mode = recognizeDbMode()
if local_mode == 'gtid':
pdb = pMysqlDb()
pdb.execute('reset master')
pwd = pSqliteDb('config').where('id=?', (1,)).getField('mysql_root')
sock = getSocketFile()
mysql_cmd = getServerDir() + '/bin/mariadb -S ' + sock + ' -uroot -p"' + pwd + \
'" ' + name
mysql_cmd_progress_bar = "pv -t -p " + file_path_sql + '|'+ mysql_cmd
print(mysql_cmd_progress_bar)
rdata = os.system(mysql_cmd_progress_bar)
return ''
def rootPwd():
return pSqliteDb('config').where(
@@ -879,7 +940,7 @@ def importDbExternalProgress():
name = args['name']
cmd = 'cd '+mw.getServerDir()+'/mdserver-web && . bin/activate && '
cmd += 'python3 '+mw.getServerDir()+'/mdserver-web/plugins/mariadb/index.py import_db_external_progress_bar {"file":"'+file+'","name":"'+name+'"}'
cmd += 'python3 '+mw.getServerDir()+'/mdserver-web/plugins/mariadb/index.py import_db_external_progress_bar {"file":"'+file+'","name":"'+name+'"}'
return mw.returnJson(True, 'ok',cmd)
def importDbExternalProgressBar():
@@ -958,7 +1019,7 @@ def deleteDbBackup():
if path != "":
full_file = path + "/" + args['filename']
os.remove(full_file)
return mw.returnJson(True, 'ok')
return mw.returnJson(True, '删除成功!')
def getDbBackupList():
@@ -1073,16 +1134,44 @@ def getDbList():
return mw.getJson(data)
def getTableList():
args = getArgs()
db_name = ""
if 'dbname' in args:
db_name = args['dbname']
if db_name == "":
return mw.returnJson(-1,"table表不能为空")
pdb = pMysqlDb()
sql = 'show tables from `%s`' % db_name
try:
data = pdb.query(sql)
except Exception as e:
return mw.returnJson(-1, str(e))
table_list = []
key = "Tables_in_%s" % db_name
for i in data:
table_list.append(i[key])
return mw.returnJson(0,"ok", table_list)
def syncGetDatabases():
pdb = pMysqlDb('mysql')
psdb = pSqliteDb('databases')
data = pdb.query('show databases')
try:
data = pdb.query('show databases')
except Exception as e:
return mw.returnJson(-1, str(e))
isError = isSqlError(data)
if isError != None:
return isError
users = pdb.query(
"select User,Host from user where User!='root' AND Host!='localhost' AND Host!=''")
try:
users = pdb.query(
"select User,Host from user where User!='root' AND Host!='localhost' AND Host!=''")
except Exception:
users = []
nameArr = ['information_schema', 'performance_schema', 'mysql', 'sys']
n = 0
@@ -1121,18 +1210,24 @@ def toDbBase(find):
if len(find['password']) < 3:
find['username'] = find['name']
find['password'] = mw.md5(str(time.time()) + find['name'])[0:10]
psdb.where("id=?", (find['id'],)).save(
'password,username', (find['password'], find['username']))
psdb.where("id=?", (find['id'],)).save('password,username', (find['password'], find['username']))
result = pdb.execute("create database `" + find['name'] + "`")
if "using password:" in str(result):
return -1
if "Connection refused" in str(result):
return -1
result = pdb.query("show databases")
db_name = []
for db_info in result:
db_name.append(db_info['Database'])
password = find['password']
__createUser(find['name'], find['username'], password, find['accept'])
return 1
if not mw.inArray(db_name, find['name']):
try:
result = pdb.execute("create database `" + find['name'] + "`")
except Exception as e:
pass
access_list = getDbUserAccess(find['name'])
if len(access_list) < 1:
__createUser(find['name'], find['username'], find['password'], find['accept'])
return 1
return 0
def syncToDatabases():
@@ -1142,7 +1237,10 @@ def syncToDatabases():
return data[1]
pdb = pMysqlDb()
result = pdb.execute("show databases")
try:
result = pdb.execute("show databases")
except Exception as e:
result = e
isError = isSqlError(result)
if isError:
return isError
@@ -1170,27 +1268,78 @@ def syncToDatabases():
return mw.returnJson(True, msg)
def setRootPwdForce(new_password, version=''):
'''
当前root密码不可用(忘记密码/连接被拒)时, 通过跳过权限校验的方式真正重置密码
'''
changed = False
try:
appCMD(version, 'stop')
openSkipGrantTables()
appCMD(version, 'start')
time.sleep(3)
resetDbRootPwd(version, new_password)
changed = True
except Exception:
changed = False
finally:
# 无论成败都恢复密码校验, 避免数据库长期处于无校验状态
appCMD(version, 'stop')
closeSkipGrantTables()
appCMD(version, 'start')
time.sleep(2)
if not changed:
return False
# 用新密码验证是否真的可以连接(启动可能较慢, 重试几次)
for i in range(10):
try:
pdb = pMysqlDb()
result = pdb.query('show databases')
if isSqlError(result) == None:
return True
except Exception:
pass
time.sleep(2)
return False
def setRootPwd(version=''):
args = getArgs()
data = checkArgs(args, ['password'])
if not data[0]:
return data[1]
password = args['password']
#强制修改
force = 0
if 'force' in args and args['force'] == '1':
force = 1
pSqliteDb('config').where('id=?', (1,)).save('mysql_root', (password,))
return mw.returnJson(True, '【强制本地记录】数据库root密码修改成功(立马检查)!')
if 'force' in args and args['force'] == '2':
force = 2
ok = setRootPwdForce(password,version)
if not ok:
return mw.returnJson(False, '【强制】修改失败,请检查MySQL运行状态!')
pSqliteDb('config').where('id=?', (1,)).save('mysql_root', (password,))
if ok and version.startswith("8"):
pdb = pMysqlDb()
try:
pdb.query("SET GLOBAL validate_password.policy=MEDIUM;")
except Exception:
pass
return mw.returnJson(True, '【强制】数据库root密码修改成功!')
password = args['password']
try:
pdb = pMysqlDb('mysql')
result = pdb.query("show databases")
isError = isSqlError(result)
if isError != None:
if force == 1:
pSqliteDb('config').where('id=?', (1,)).save('mysql_root', (password,))
return mw.returnJson(True, '【强制修改】数据库root密码修改成功(不意为成功连接数据)!')
return isError
cmd = "ALTER USER 'root'@'localhost' IDENTIFIED BY '" + password + "';"
@@ -1201,11 +1350,7 @@ def setRootPwd(version=''):
orm = pMysqlDb()
orm.execute("flush privileges")
msg = ''
if force == 1:
msg = ',无须强制!'
return mw.returnJson(True, '数据库root密码修改成功!' + msg)
return mw.returnJson(True, '数据库root密码修改成功!')
except Exception as ex:
return mw.returnJson(False, '修改错误:' + str(ex))
@@ -1224,18 +1369,33 @@ def setUserPwd(version=''):
psdb = pSqliteDb('databases')
data = psdb.field('id,name,accept').where('id=?', (uid,)).find()
cmd = "SET PASSWORD FOR '" + username + \
"'@'localhost' = PASSWORD('" + newpassword + "')"
r = pdb.execute(cmd)
# print(cmd, r)
accept = data['accept']
alist = accept.split(',')
for x in alist:
cmd = "SET PASSWORD FOR '" + username + \
"'@'" + x + "' = PASSWORD('" + newpassword + "')"
r = pdb.execute(cmd)
# print(cmd, r)
hosts = ['localhost']
if accept:
for x in accept.split(','):
x = x.strip()
if len(x) > 0 and x != 'localhost':
hosts.append(x)
# 兼容所有 MariaDB 版本:
# 优先 ALTER USER(10.2+),用户不存在则 CREATE USER(10.0.2+),
# 旧版本不支持以上语法时回退 GRANT ... IDENTIFIED BY
for x in hosts:
sqls = [
"ALTER USER '%s'@'%s' IDENTIFIED BY '%s'" % (username, x, newpassword),
"CREATE USER '%s'@'%s' IDENTIFIED BY '%s'" % (username, x, newpassword),
"GRANT USAGE ON *.* TO '%s'@'%s' IDENTIFIED BY '%s'" % (username, x, newpassword),
]
err = None
for sql in sqls:
try:
pdb.execute(sql)
err = None
break
except Exception as e:
err = e
if err != None:
raise err
psdb.where("id=?", (uid,)).setField('password', newpassword)
@@ -1308,16 +1468,21 @@ def addDb():
if psdb.where("name=? or username=?", (dbname, dbuser)).count():
return mw.returnJson(False, '数据库已存在!')
result = pdb.execute("create database `" + dbname +
"` DEFAULT CHARACTER SET " + codeing + " COLLATE " + codeStr)
try:
result = pdb.execute("create database `" + dbname +"` DEFAULT CHARACTER SET " + codeing + " COLLATE " + codeStr)
except Exception as e:
result = e
# print result
isError = isSqlError(result)
if isError != None:
return isError
pdb.execute("drop user '" + dbuser + "'@'localhost'")
for a in address.split(','):
pdb.execute("drop user '" + dbuser + "'@'" + a + "'")
db_users_access = getDbUserAccess(dbuser)
for user_access in db_users_access:
try:
pdb.execute("drop user `%s`@'%s'" % (db_user, user_access))
except Exception:
pass
__createUser(dbname, dbuser, password, address)
@@ -1342,14 +1507,18 @@ def delDb():
accept = find['accept']
username = find['username']
# 删除MYSQL
result = pdb.execute("drop database `" + name + "`")
# 删除MYSQL(库或用户可能已不存在,失败忽略,保证面板记录可删除)
try:
pdb.execute("drop database `" + name + "`")
except Exception:
pass
users = pdb.query("select Host from user where User='" +
username + "' AND Host!='localhost'")
pdb.execute("drop user '" + username + "'@'localhost'")
for us in users:
pdb.execute("drop user '" + username + "'@'" + us["Host"] + "'")
db_users_access = getDbUserAccess(username)
for user_access in db_users_access:
try:
pdb.execute("drop user '" + username + "'@'%s'" % (user_access,))
except Exception:
pass
pdb.execute("flush privileges")
# 删除SQLITE
@@ -1359,57 +1528,120 @@ def delDb():
return mw.returnJson(False, '删除失败!' + str(ex))
def getDbUserAccess(username):
pdb = pMysqlDb()
accs = []
try:
users = pdb.query("select Host from mysql.user where User='" + username + "'")
except Exception as e:
return accs
for c in users:
accs.append(c["Host"])
return accs
def getDbUserAccessDiff(db_access, input_access):
add = []
delete = []
host_var = 'localhost'
local_ipvar = '127.0.0.1'
local_ip6var = '::1'
for ac in input_access:
if ac == host_var:
continue
if ac == local_ipvar:
continue
if ac == local_ip6var:
continue
if mw.inArray(db_access,ac):
continue
add.append(ac)
if not mw.inArray(db_access, local_ipvar) and not mw.inArray(add, local_ipvar):
add.append(local_ipvar)
if not mw.inArray(db_access, local_ip6var) and not mw.inArray(add, local_ip6var):
add.append(local_ip6var)
for ac in db_access:
if ac == host_var:
continue
if ac == local_ipvar:
continue
if ac == local_ip6var:
continue
if mw.inArray(input_access,ac):
continue
delete.append(ac)
if mw.inArray(delete, local_ipvar):
delete.remove(local_ipvar)
if mw.inArray(delete, local_ip6var):
delete.remove(local_ip6var)
return {"add":add,"delete":delete}
def getDbAccess():
args = getArgs()
data = checkArgs(args, ['username'])
if not data[0]:
return data[1]
username = args['username']
pdb = pMysqlDb('mysql')
users = pdb.query("select Host from user where User='" +
username + "' AND Host!='localhost'")
users = getDbUserAccess(username)
if len(users) == 1:
return mw.returnJson(True, "localhost")
userStr = ','.join(users)
if userStr == '127.0.0.1,localhost':
return mw.returnJson(True, 'localhost')
if userStr == '127.0.0.1,::1,localhost':
return mw.returnJson(True, 'localhost')
isError = isSqlError(users)
if isError != None:
return isError
if len(users) < 1:
return mw.returnJson(True, "127.0.0.1")
accs = []
for c in users:
accs.append(c["Host"])
userStr = ','.join(accs)
return mw.returnJson(True, userStr)
def setDbAccessByArgs(username,access):
pdb = pMysqlDb()
psdb = pSqliteDb('databases')
dbname = psdb.where('username=?', (username,)).getField('name')
password = psdb.where("username=?", (username,)).getField('password')
if username == 'root':
dbname = '*'
password = pSqliteDb('config').where('id=?', (1,)).getField('mysql_root')
db_users_access = getDbUserAccess(username)
diff_access = getDbUserAccessDiff(db_users_access,access.split(','))
# print(diff_access)
add_access_list = diff_access["add"]
pdb.execute("flush privileges")
for add_access in add_access_list:
pdb.execute("CREATE USER `%s`@`%s` IDENTIFIED BY '%s'" % (username, add_access, password))
pdb.execute("grant all privileges on %s.* to `%s`@`%s`" % (dbname, username, add_access))
pdb.execute("flush privileges")
delete_access_list = diff_access["delete"]
for del_access in delete_access_list:
try:
pdb.execute("drop user '" + username + "'@'" + del_access + "'")
except Exception:
pass
psdb.where('username=?', (username,)).save('accept,rw', (access, 'rw',))
return True
def setDbAccess():
args = getArgs()
data = checkArgs(args, ['username', 'access'])
if not data[0]:
return data[1]
name = args['username']
username = args['username']
access = args['access']
pdb = pMysqlDb('mysql')
psdb = pSqliteDb('databases')
dbname = psdb.where('username=?', (name,)).getField('name')
if name == 'root':
password = pSqliteDb('config').where(
'id=?', (1,)).getField('mysql_root')
else:
password = psdb.where("username=?", (name,)).getField('password')
users = pdb.query("select Host from user where User='" +
name + "' AND Host!='localhost'")
for us in users:
pdb.execute("drop user '" + name + "'@'" + us["Host"] + "'")
__createUser(dbname, name, password, access)
psdb.where('username=?', (name,)).save('accept,rw', (access, 'rw',))
setDbAccessByArgs(username, access)
return mw.returnJson(True, '设置成功!')
def openSkipGrantTables():
@@ -1427,10 +1659,11 @@ def closeSkipGrantTables():
return True
def resetDbRootPwd(version):
def resetDbRootPwd(version, newpwd=''):
serverdir = getServerDir()
myconf = serverdir + "/etc/my.cnf"
pwd = mw.getRandomString(16)
# newpwd 为空时生成随机密码, 强制修改时传入用户指定的密码
pwd = newpwd if newpwd != '' else mw.getRandomString(16)
pSqliteDb('config').where('id=?', (1,)).save('mysql_root', (pwd,))
db_option = "-S " + serverdir + "/mysql.sock"
@@ -1445,30 +1678,34 @@ def resetDbRootPwd(version):
def fixDbAccess(version):
pdb = pMysqlDb()
mdb_ddir = getDataDir()
if not os.path.exists(mdb_ddir):
return mw.returnJson(False, '数据目录不存在,尝试重启重建!')
# 1) 数据目录不存在或未初始化(缺少 mysql 系统库): 删除后重建, 启动时会自动 mariadb-install-db 初始化
if not os.path.exists(mdb_ddir + '/mysql'):
try:
appCMD(version, 'stop')
if os.path.exists(mdb_ddir):
mw.execShell('rm -rf ' + mdb_ddir)
appCMD(version, 'start')
return mw.returnJson(True, '数据目录不存在,已重建并初始化!')
except Exception as e:
return mw.returnJson(False, '重建失败:' + str(e))
try:
psdb = pSqliteDb('databases')
pdb = pMysqlDb()
data = pdb.query('show databases')
isError = isSqlError(data)
if isError != None:
# 重置密码
appCMD(version, 'stop')
openSkipGrantTables()
appCMD(version, 'start')
time.sleep(3)
resetDbRootPwd(version)
if isError == None:
return mw.returnJson(True, '正常无需修复!')
appCMD(version, 'stop')
closeSkipGrantTables()
appCMD(version, 'start')
return mw.returnJson(True, '修复成功!')
return mw.returnJson(True, '正常无需修复!')
# 2) 密码错误 -> 跳过权限校验重置密码, 并用新密码验证连接
if not setRootPwdForce(mw.getRandomString(16), version):
return mw.returnJson(False, '密码重置失败,请检查数据库运行状态!')
return mw.returnJson(True, '修复成功,root密码已重置!')
except Exception as e:
return mw.returnJson(False, '修复失败请重试!')
# 连接阶段抛异常一般是密码不可用, 仍尝试重置
if setRootPwdForce(mw.getRandomString(16), version):
return mw.returnJson(True, '修复成功,root密码已重置!')
return mw.returnJson(False, '修复失败:' + str(e))
def setDbRw(version=''):
@@ -1484,8 +1721,11 @@ def setDbRw(version=''):
pdb = pMysqlDb('mysql')
psdb = pSqliteDb('databases')
dbname = psdb.where("id=?", (uid,)).getField('name')
users = pdb.query(
"select Host from user where User='" + username + "'")
try:
users = pdb.query(
"select Host from user where User='" + username + "'")
except Exception as e:
return mw.returnJson(-1, str(e))
# show grants for demo@"127.0.0.1";
for x in users:
@@ -1493,7 +1733,10 @@ def setDbRw(version=''):
sql = "REVOKE ALL PRIVILEGES ON `" + dbname + \
"`.* FROM '" + username + "'@'" + x["Host"] + "';"
r = pdb.query(sql)
try:
pdb.query(sql)
except Exception:
pass
# print(sql, r)
if rw == 'rw':
@@ -1505,7 +1748,10 @@ def setDbRw(version=''):
else:
sql = "GRANT all privileges ON " + dbname + ".* TO " + \
username + "@'" + x["Host"] + "'"
pdb.execute(sql)
try:
pdb.execute(sql)
except Exception as e:
return mw.returnJson(False, '切换失败!' + str(e))
pdb.execute("flush privileges")
r = psdb.where("id=?", (uid,)).setField('rw', rw)
# print(r)
@@ -1521,11 +1767,17 @@ def getDbInfo():
db_name = args['name']
pdb = pMysqlDb()
# print 'show tables from `%s`' % db_name
tables = pdb.query('show tables from `%s`' % db_name)
try:
tables = pdb.query('show tables from `%s`' % db_name)
except Exception as e:
return mw.returnJson(-1, str(e))
ret = {}
sql = "select sum(DATA_LENGTH)+sum(INDEX_LENGTH) as sum_size from information_schema.tables where table_schema='%s'" % db_name
data_sum = pdb.query(sql)
try:
data_sum = pdb.query(sql)
except Exception as e:
return mw.returnJson(-1, str(e))
data = 0
if data_sum[0]['sum_size'] != None:
@@ -1539,7 +1791,12 @@ def getDbInfo():
for i in tables:
tb_sql = "show table status from `%s` where name = '%s'" % (db_name, i[
table_key])
table = pdb.query(tb_sql)
try:
table = pdb.query(tb_sql)
except Exception:
continue
if len(table) < 1:
continue
tmp = {}
tmp['type'] = table[0]["Engine"]
@@ -1572,7 +1829,10 @@ def repairTable():
db_name = args['db_name']
tables = json.loads(args['tables'])
pdb = pMysqlDb()
mtable = pdb.query('show tables from `%s`' % db_name)
try:
mtable = pdb.query('show tables from `%s`' % db_name)
except Exception as e:
return mw.returnJson(-1, str(e))
ret = []
key = "Tables_in_" + db_name
@@ -1597,7 +1857,10 @@ def optTable():
db_name = args['db_name']
tables = json.loads(args['tables'])
pdb = pMysqlDb()
mtable = pdb.query('show tables from `%s`' % db_name)
try:
mtable = pdb.query('show tables from `%s`' % db_name)
except Exception as e:
return mw.returnJson(-1, str(e))
ret = []
key = "Tables_in_" + db_name
for i in mtable:
@@ -1622,7 +1885,10 @@ def alterTable():
tables = json.loads(args['tables'])
table_type = args['table_type']
pdb = pMysqlDb()
mtable = pdb.query('show tables from `%s`' % db_name)
try:
mtable = pdb.query('show tables from `%s`' % db_name)
except Exception as e:
return mw.returnJson(-1, str(e))
ret = []
key = "Tables_in_" + db_name
@@ -1697,26 +1963,9 @@ def setDbrunMode(version=''):
con = re.sub(rep, rep_after, con)
mw.writeFile(path, con)
if version == '5.6':
dbreload = 'yes'
else:
db = pMysqlDb()
# The value of @@GLOBAL.GTID_MODE can only be changed one step at a
# time: OFF <-> OFF_PERMISSIVE <-> ON_PERMISSIVE <-> ON. Also note that
# this value must be stepped up or down simultaneously on all servers.
# See the Manual for instructions.
if mode == 'classic':
db.query('set global enforce_gtid_consistency=off')
db.query('set global gtid_mode=on')
db.query('set global gtid_mode=on_permissive')
db.query('set global gtid_mode=off_permissive')
db.query('set global gtid_mode=off')
elif mode == 'gtid':
db.query('set global enforce_gtid_consistency=on')
db.query('set global gtid_mode=off')
db.query('set global gtid_mode=off_permissive')
db.query('set global gtid_mode=on_permissive')
db.query('set global gtid_mode=on')
# MariaDB 无 gtid_mode/enforce_gtid_consistency 等全局变量,
# binlog 模式由 etc/mode 配置文件生效,统一重启
dbreload = 'yes'
if dbreload == "yes":
restart(version)
@@ -1750,17 +1999,18 @@ def setDbMasterAccess():
pdb = pMysqlDb()
psdb = pSqliteDb('master_replication_user')
password = psdb.where("username=?", (username,)).getField('password')
users = pdb.query("select Host from user where User='" +
username + "' AND Host!='localhost'")
for us in users:
pdb.execute("drop user '" + username + "'@'" + us["Host"] + "'")
db_users_access = getDbUserAccess(username)
for user_access in db_users_access:
try:
pdb.execute("drop user '" + username + "'@'%s'" % (user_access,))
except Exception:
pass
dbname = '*'
for a in access.split(','):
pdb.execute(
"CREATE USER `%s`@`%s` IDENTIFIED BY '%s'" % (username, a, password))
pdb.execute(
"grant all privileges on %s.* to `%s`@`%s`" % (dbname, username, a))
pdb.execute("CREATE USER `%s`@`%s` IDENTIFIED BY '%s'" % (username, a, password))
pdb.execute("grant all privileges on %s.* to `%s`@`%s`" % (dbname, username, a))
pdb.execute("flush privileges")
psdb.where('username=?', (username,)).save('accept', (access,))
@@ -2140,10 +2390,10 @@ def getMasterRepSlaveUserCmd(version):
base_sql = "CHANGE MASTER " + connection_name + "TO MASTER_HOST='" + ip + "', MASTER_PORT=" + port + ", MASTER_USER='" + \
clist[0]['username'] + "', MASTER_PASSWORD='" + \
clist[0]['password'];
sql = ''
sql = '<span class="set-info c7 ta_center">经典模式</span><hr style="margin-top: 5px;margin-bottom: 10px;"/>'
sql += base_sql + "', MASTER_LOG_FILE='" + mstatus[0]["File"] + \
"',MASTER_LOG_POS=" + str(mstatus[0]["Position"])
sql += "<br/><hr/>";
sql += '<br/><hr/><span class="set-info c7 ta_center">GTID模式</span><hr style="margin-top: 5px;margin-bottom: 10px;"/>'
sql += base_sql + "',MASTER_USE_GTID=slave_pos,MASTER_CONNECT_RETRY=10;";
sql += "<br/>";
@@ -2165,13 +2415,25 @@ def delMasterRepSlaveUser(version=''):
pdb = pMysqlDb()
psdb = pSqliteDb('master_replication_user')
pdb.execute("drop user '" + name + "'@'%'")
pdb.execute("drop user '" + name + "'@'localhost'")
try:
pdb.execute("drop user '" + name + "'@'%'")
except Exception:
pass
try:
pdb.execute("drop user '" + name + "'@'localhost'")
except Exception:
pass
users = pdb.query("select Host from user where User='" +
name + "' AND Host!='localhost'")
try:
users = pdb.query("select Host from user where User='" +
name + "' AND Host!='localhost'")
except Exception:
users = []
for us in users:
pdb.execute("drop user '" + name + "'@'" + us["Host"] + "'")
try:
pdb.execute("drop user '" + name + "'@'" + us["Host"] + "'")
except Exception:
pass
psdb.where("username=?", (args['username'],)).delete()
@@ -2186,7 +2448,10 @@ def updateMasterRepSlaveUser(version=''):
pdb = pMysqlDb()
psdb = pSqliteDb('master_replication_user')
pdb.execute("drop user '" + args['username'] + "'@'%'")
try:
pdb.execute("drop user '" + args['username'] + "'@'%'")
except Exception:
pass
pdb.execute("GRANT REPLICATION SLAVE ON *.* TO '" +
args['username'] + "'@'%' identified by '" + args['password'] + "'")
@@ -2417,13 +2682,17 @@ def updateSlaveSSH(version=''):
def getSlaveList(version=''):
db = pMysqlDb()
dlist = db.query('show slave status')
if len(dlist) == 0:
dlist = db.query('show all slaves status')
try:
dlist = db.query('show slave status')
if len(dlist) == 0:
dlist = db.query('show all slaves status')
except Exception as e:
return mw.returnJson(-1, str(e))
data = {}
data['data'] = dlist
return mw.getJson(data)
# 状态字段中包含 datetime 等对象,需转成字符串后才能序列化
return json.dumps(data, default=str)
def trySlaveSyncBugfix(version=''):
if status(version) == 'stop':
@@ -2572,9 +2841,12 @@ def initSlaveStatusSyncUser(version=''):
def initSlaveStatusSSH(version=''):
db = pMysqlDb()
dlist = db.query('show slave status')
if len(dlist) == 0:
dlist = db.query('show all slaves status')
try:
dlist = db.query('show slave status')
if len(dlist) == 0:
dlist = db.query('show all slaves status')
except Exception as e:
return mw.returnJson(-1, str(e))
conn = pSqliteDb('slave_id_rsa')
ssh_list = conn.field('ip,port,id_rsa,db_user').select()
@@ -3332,8 +3604,10 @@ def installPreInspection(version):
def uninstallPreInspection(version):
stop(version)
if mw.isDebugMode():
return 'ok'
# if mw.isDebugMode():
# return 'ok'
from utils.plugin import plugin as MwPlugin
MwPlugin.instance().removeIndex(getPluginName(), version)
return "请手动删除MariaDB[{}]<br/> rm -rf {}".format(version, getServerDir())
@@ -3397,6 +3671,8 @@ if __name__ == "__main__":
print(rootPwd())
elif func == 'get_db_list':
print(getDbList())
elif func == 'get_table_list':
print(getTableList())
elif func == 'set_db_backup':
print(setDbBackup())
elif func == 'import_db_backup':

View File

@@ -9,7 +9,7 @@
"uninstall_pre_inspection":true,
"checks": "server/mariadb",
"path": "server/mariadb",
"versions":["10.6","10.7","10.8","10.9","10.11","11.0","11.1","11.2","11.3","11.4","11.5","11.6","11.7","11.8","12.0"],
"versions":["10.6","10.7","10.8","10.9","10.11","11.0","11.1","11.2","11.3","11.4","11.5","11.6","11.7","11.8","12.0","12.1","12.3"],
"shell":"install.sh",
"checks":"server/mariadb",
"path":"server/mariadb",

View File

@@ -507,11 +507,11 @@ function setRootPwd(type, pwd){
var index = layer.open({
type: 1,
area: '500px',
area: '800px',
title: '修改数据库密码',
closeBtn: 1,
shift: 5,
btn:["提交", "关闭", "复制ROOT密码", "强制修改"],
btn:["提交", "关闭", "复制ROOT密码", "修改本地ROOT记录", "强改ROOT密码"],
shadeClose: true,
content: "<form class='bt-form pd20' id='mod_pwd'>\
<div class='line'>\
@@ -537,7 +537,7 @@ function setRootPwd(type, pwd){
return false;
},
btn4:function(layerIndex){
layer.confirm('强制修改,是为了在重建时使用,确定强制?', {
layer.confirm('修改本地ROOT记录,确定修改?', {
btn: ['确定', '取消']
}, function(index, layero){
layer.close(index);
@@ -551,6 +551,22 @@ function setRootPwd(type, pwd){
});
});
return false;
},
btn5:function(layerIndex){
layer.confirm('强制修改MySQL密码,确定强制? (比较耗时)', {
btn: ['确定', '取消']
}, function(index, layero){
layer.close(index);
var password = $("#MyPassword").val();
myPost('set_root_pwd', {password:password,force:'2'}, function(data){
var rdata = $.parseJSON(data.data);
showMsg(rdata.msg,function(){
layer.close(layerIndex);
dbList();
},{icon: rdata.status ? 1 : 2});
});
});
return false;
}
});
}
@@ -617,7 +633,7 @@ function setDbAccess(username){
<span class='tname'>访问权限</span>\
<div class='info-r '>\
<select class='bt-input-text mr5' name='dataAccess' style='width:100px'>\
<option value='127.0.0.1'>本地服务器</option>\
<option value='localhost'>本地服务器</option>\
<option value=\"%\">所有人</option>\
<option value='ip'>指定IP</option>\
</select>\
@@ -625,9 +641,9 @@ function setDbAccess(username){
</div>\
</form>",
success:function(){
if (rdata.msg == '127.0.0.1'){
$('select[name="dataAccess"]').find("option[value='127.0.0.1']").attr("selected",true);
} else if (rdata.msg == '%'){
if (rdata.msg == 'localhost'){
$('select[name="dataAccess"]').find("option[value='localhost']").attr("selected",true);
} else if (rdata.msg.indexOf("%") > -1){
$('select[name="dataAccess"]').find('option[value="%"]').attr("selected",true);
} else if ( rdata.msg == 'ip' ){
$('select[name="dataAccess"]').find('option[value="ip"]').attr("selected",true);
@@ -914,7 +930,7 @@ function delBackup(filename, name, path){
path = "";
}
myPost('delete_db_backup',{filename:filename,path:path},function(){
layer.msg('执行成功!');
layer.msg(rdata.msg, { icon: rdata.status ? 1 : 2 });
setTimeout(function(){
setBackupReq(name);
},2000);
@@ -931,13 +947,57 @@ function importBackup(file,name){
});
}
function importDbExternal(file,name){
myPost('import_db_external',{file:file,name:name}, function(data){
layer.msg('执行成功!');
function importBackupProgress(file,name){
myPost('import_db_backup_progress',{file:file,name:name}, function(data){
var rdata = $.parseJSON(data.data);
layer.open({
title: "手动导入命令CMD【显示进度】",
area: ['600px', '180px'],
type:1,
closeBtn: 1,
shadeClose: false,
btn:["复制","取消"],
content: '<div class="pd15">\
<div class="divtable">\
<pre class="layui-code">'+rdata.data+'</pre>\
</div>\
</div>',
success:function(){
copyText(rdata.data);
},
yes:function(){
copyText(rdata.data);
}
});
});
}
function importDbProgress(file,name){
myPost('import_db_progress',{file:file,name:name}, function(data){
var rdata = $.parseJSON(data.data);
layer.open({
title: "手动导入命令CMD【显示进度】",
area: ['600px', '180px'],
type:1,
closeBtn: 1,
shadeClose: false,
btn:["复制","取消"],
content: '<div class="pd15">\
<div class="divtable">\
<pre class="layui-code">'+rdata.data+'</pre>\
</div>\
</div>',
success:function(){
copyText(rdata.data);
},
yes:function(){
copyText(rdata.data);
}
});
});
}
function importDbExternalProgress(file,name){
myPost('import_db_external_progress',{file:file,name:name}, function(data){
var rdata = $.parseJSON(data.data);
@@ -1086,12 +1146,13 @@ function setBackup(db_name){
var layerIndex = layer.open({
type: 1,
title: "数据库备份详情",
area: ['600px', '280px'],
area: ['700px', '280px'],
closeBtn: 1,
shadeClose: false,
content: '<div class="pd15">\
<div class="db_list">\
<button id="btn_backup" class="btn btn-success btn-sm" type="button">备份</button>\
<button id="btn_backup_reload" class="btn btn-success btn-sm" type="button">刷新</button>\
<button id="btn_local_import" class="btn btn-success btn-sm" type="button">外部导入</button>\
</div >\
<div class="divtable">\
@@ -1123,6 +1184,10 @@ function setBackup(db_name){
setLocalImport(db_name);
});
$('#btn_backup_reload').click(function(){
setBackupReq(db_name);
});
setBackupReq(db_name);
},
});
@@ -1140,6 +1205,7 @@ function setBackupReq(db_name, obj){
<td><span> ' + rdata.data[i]['time'] + '</span></td>\
<td style="text-align: right;">\
<a class="btlink" onclick="importBackup(\'' + rdata.data[i]['name'] + '\',\'' +db_name+ '\')">导入</a> | \
<a class="btlink" onclick="importBackupProgress(\'' + rdata.data[i]['name'] + '\',\'' +db_name+ '\')">导入进度</a> | \
<a class="btlink" onclick="downloadBackup(\'' + rdata.data[i]['file'] + '\')">下载</a> | \
<a class="btlink" onclick="delBackup(\'' + rdata.data[i]['name'] + '\',\'' +db_name+ '\')">删除</a>\
</td>\
@@ -1732,7 +1798,7 @@ function getMasterRepSlaveUserCmd(username, db=''){
var loadOpen = layer.open({
type: 1,
title: '同步命令',
title: '同步命令[ 1-经典模式,2-GTID ]',
area: '500px',
content:"<form class='bt-form pd20 pb70' id='add_master'>\
<div class='line' style='word-wrap: break-word;word-break: normal;'>"+cmd+"</div>\
@@ -1780,7 +1846,7 @@ function setDbMasterAccess(username){
<span class='tname'>访问权限</span>\
<div class='info-r '>\
<select class='bt-input-text mr5' name='dataAccess' style='width:100px'>\
<option value='127.0.0.1'>本地服务器</option>\
<option value='localhost'>本地服务器</option>\
<option value=\"%\">所有人</option>\
<option value='ip'>指定IP</option>\
</select>\
@@ -1788,9 +1854,9 @@ function setDbMasterAccess(username){
</div>\
</form>",
success:function(){
if (rdata.msg == '127.0.0.1'){
$('select[name="dataAccess"]').find("option[value='127.0.0.1']").attr("selected",true);
} else if (rdata.msg == '%'){
if (rdata.msg == 'localhost'){
$('select[name="dataAccess"]').find("option[value='localhost']").attr("selected",true);
} else if (rdata.msg.indexOf("%") > -1 ){
$('select[name="dataAccess"]').find('option[value="%"]').attr("selected",true);
} else if ( rdata.msg == 'ip' ){
$('select[name="dataAccess"]').find('option[value="ip"]').attr("selected",true);

View File

@@ -29,7 +29,34 @@ import core.db as db
class backupTools:
def backupDatabase(self, name, count):
def getDbBackupList(self,dbname=''):
bkDir = mw.getFatherDir() + '/backup/database/mariadb'
if not os.path.isdir(bkDir):
return []
blist = os.listdir(bkDir)
r = []
bname = 'db_' + dbname
blen = len(bname)
for x in blist:
fbstr = x[0:blen]
if fbstr == bname:
r.append(x)
# 文件名按时间戳命名,排序后即为时间顺序(旧->新)
r.sort()
return r
def backupDatabase(self, params, count):
params_args = params.split("@")
name = params_args[0]
table_name = ''
if len(params_args) > 1:
table_name = params_args[1]
backup_name = name
if table_name != '':
backup_name = name+'@'+table_name
db_path = mw.getServerDir() + '/mariadb'
db_sock = mw.getServerDir() + '/mariadb/'
db_name = 'mysql'
@@ -48,7 +75,7 @@ class backupTools:
if not os.path.exists(backup_path):
mw.execShell("mkdir -p " + backup_path)
filename = backup_path + "/db_" + name + "_" + \
filename = backup_path + "/db_" + backup_name + "_" + \
time.strftime('%Y%m%d_%H%M%S', time.localtime()) + ".sql.gz"
mysql_root = mw.M('config').dbPos(db_path, db_name).where(
@@ -71,45 +98,41 @@ class backupTools:
cmd = db_path + "/bin/mariadb-dump --defaults-file=" + my_conf_path + " --single-transaction --quick --default-character-set=utf8 " + \
name + " | gzip > " + filename
if table_name != '':
cmd = db_path + "/bin/mariadb-dump --defaults-file=" + my_conf_path + " --single-transaction --quick --default-character-set=utf8 " + \
name + " " + table_name + " | gzip > " + filename
mw.execShell(cmd)
if not os.path.exists(filename):
endDate = time.strftime('%Y/%m/%d %X', time.localtime())
log = "数据库[" + name + "]备份失败!"
print("★[" + endDate + "] " + log)
print(
"----------------------------------------------------------------------------")
return
mycnf = mw.readFile(db_path + '/etc/my.cnf')
mycnf = mycnf.replace(subStr, sea)
if len(mycnf) > 100:
mw.writeFile(db_path + '/etc/my.cnf', mycnf)
if not os.path.exists(filename):
endDate = time.strftime('%Y/%m/%d %X', time.localtime())
log = "数据库[" + name + "]备份失败!"
print("★[" + endDate + "] " + log)
print("----------------------------------------------------------------------------")
return
endDate = time.strftime('%Y/%m/%d %X', time.localtime())
outTime = time.time() - startTime
pid = mw.M('databases').dbPos(db_path, db_name).where(
'name=?', (name,)).getField('id')
mw.M('backup').add('type,name,pid,filename,addtime,size', (3, os.path.basename(
filename), pid, filename, endDate, os.path.getsize(filename)))
log = "数据库[" + name + "]备份成功,用时[" + str(round(outTime, 2)) + "]秒"
log = "数据库[" + backup_name + "]备份成功,用时[" + str(round(outTime, 2)) + "]秒"
mw.writeLog('计划任务', log)
print("★[" + endDate + "] " + log)
print("|---保留最新的[" + count + "]份备份")
print("|---文件名:" + filename)
backups = self.getDbBackupList(backup_name)
# 清理多余备份
backups = mw.M('backup').where(
'type=? and pid=?', ('3', pid)).field('id,filename').select()
num = len(backups) - int(count)
if num > 0:
for backup in backups:
mw.execShell("rm -f " + backup['filename'])
mw.M('backup').where('id=?', (backup['id'],)).delete()
mw.execShell("rm -f " + backup_path + "/"+backup)
num -= 1
print("|---已清理过期备份文件:" + backup['filename'])
print("|---已清理过期文件:" + backup)
if num < 1:
break

View File

@@ -54,7 +54,7 @@ Install_app()
# wget --no-check-certificate -O ${mariadbDir}/mariadb-${MY_VER}.tar.gz --tries=3 https://mirrors.aliyun.com/mariadb/mariadb-${MY_VER}/source/mariadb-${MY_VER}.tar.gz
# fi
# https://downloads.mariadb.org/interstitial/mariadb-10.9.1/source/mariadb-10.9.1.tar.gz
# https://downloads.mariadb.org/interstitial/mariadb-11.8.3/source/mariadb-11.8.3.tar.gz
if [ ! -f ${mariadbDir}/mariadb-${MY_VER}.tar.gz ];then
wget --no-check-certificate -O ${mariadbDir}/mariadb-${MY_VER}.tar.gz --tries=3 https://archive.mariadb.org/mariadb-${MY_VER}/source/mariadb-${MY_VER}.tar.gz
fi

View File

@@ -0,0 +1,120 @@
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin
export PATH
#https://dev.mysql.com/downloads/mysql/5.5.html#downloads
#https://dev.mysql.com/downloads/file/?id=480541
curPath=`pwd`
rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
sysName=`uname`
mariadbDir=${serverPath}/source/mariadb
MY_VER=12.3.3
Install_app()
{
mkdir -p ${mariadbDir}
echo '正在安装脚本文件...'
if [ "$sysName" != "Darwin" ];then
mkdir -p /var/log/mariadb
touch /var/log/mariadb/mariadb.log
fi
# ----- cpu start ------
if [ -z "${cpuCore}" ]; then
cpuCore="1"
fi
if [ -f /proc/cpuinfo ];then
cpuCore=`cat /proc/cpuinfo | grep "processor" | wc -l`
fi
MEM_INFO=$(free -m|grep Mem|awk '{printf("%.f",($2)/1024)}')
if [ "${cpuCore}" != "1" ] && [ "${MEM_INFO}" != "0" ];then
if [ "${cpuCore}" -gt "${MEM_INFO}" ];then
cpuCore="${MEM_INFO}"
fi
else
cpuCore="1"
fi
if [ "$cpuCore" -gt "2" ];then
cpuCore=`echo "$cpuCore" | awk '{printf("%.f",($1)*0.8)}'`
else
cpuCore="1"
fi
# ----- cpu end ------
# if [ ! -f ${mariadbDir}/mariadb-${MY_VER}.tar.gz ];then
# wget --no-check-certificate -O ${mariadbDir}/mariadb-${MY_VER}.tar.gz --tries=3 https://mirrors.aliyun.com/mariadb/mariadb-${MY_VER}/source/mariadb-${MY_VER}.tar.gz
# fi
# https://archive.mariadb.org/mariadb-12.3.3/source/mariadb-12.3.3.tar.gz
if [ ! -f ${mariadbDir}/mariadb-${MY_VER}.tar.gz ];then
wget --no-check-certificate -O ${mariadbDir}/mariadb-${MY_VER}.tar.gz --tries=3 https://archive.mariadb.org/mariadb-${MY_VER}/source/mariadb-${MY_VER}.tar.gz
fi
if [ ! -d ${mariadbDir}/mariadb-${MY_VER} ];then
cd ${mariadbDir} && tar -zxvf ${mariadbDir}/mariadb-${MY_VER}.tar.gz
fi
INSTALL_CMD=cmake
# check cmake version
CMAKE_VERSION=`cmake -version | grep version | awk '{print $3}' | awk -F '.' '{print $1}'`
if [ "$CMAKE_VERSION" -eq "2" ];then
mkdir -p /var/log/mariadb
touch /var/log/mariadb/mariadb.log
INSTALL_CMD=cmake3
fi
if [ ! -d $serverPath/mariadb ];then
cd ${mariadbDir}/mariadb-${MY_VER} && ${INSTALL_CMD} \
-DCMAKE_INSTALL_PREFIX=$serverPath/mariadb \
-DMYSQL_DATADIR=$serverPath/mariadb/data/ \
-DMYSQL_USER=mysql \
-DMYSQL_UNIX_ADDR=$serverPath/mariadb/mysql.sock \
-DWITH_MYISAM_STORAGE_ENGINE=1 \
-DWITH_INNOBASE_STORAGE_ENGINE=1 \
-DWITH_MEMORY_STORAGE_ENGINE=1 \
-DENABLED_LOCAL_INFILE=1 \
-DWITH_PARTITION_STORAGE_ENGINE=1 \
-DEXTRA_CHARSETS=all \
-DDEFAULT_CHARSET=utf8mb4 \
-DDEFAULT_COLLATION=utf8mb4_general_ci \
-DCMAKE_C_COMPILER=/usr/bin/gcc \
-DCMAKE_CXX_COMPILER=/usr/bin/g++
make -j${cpuCore} && make install && make clean
if [ -d $serverPath/mariadb ];then
echo '12.1' > $serverPath/mariadb/version.pl
echo '安装完成'
else
echo '安装失败'
echo 'install fail'>&2
exit 1
fi
fi
if [ -d ${mariadbDir}/mariadb-${MY_VER} ];then
rm -rf ${mariadbDir}/mariadb-${MY_VER}
fi
}
Uninstall_app()
{
rm -rf $serverPath/mariadb
echo '卸载完成'
}
action=$1
if [ "${1}" = 'install' ];then
Install_app
else
Uninstall_app
fi

View File

@@ -40,6 +40,20 @@ def getServerDir():
return mw.getServerDir() + '/' + getPluginName()
def getBackupDir():
bk_path = mw.getBackupDir() + "/database/mongodb"
if not os.path.isdir(bk_path):
mw.execShell("mkdir -p {}".format(bk_path))
return bk_path
def getImportDir():
import_path = mw.getBackupDir() + "/mongodb_import"
if not os.path.isdir(import_path):
mw.execShell("mkdir -p {}".format(import_path))
return import_path
def getInitDFile():
if app_debug:
return '/tmp/' + getPluginName()
@@ -188,6 +202,23 @@ def pSqliteDb(dbname='users'):
conn = mw.M(dbname).dbPos(getServerDir(), name)
return conn
def newMongoClient(**kwargs):
'''兼容 pymongo 3.x/4.x:directConnection 仅 pymongo 4.0+ 支持'''
import pymongo
if getattr(pymongo, 'version_tuple', (3, 0))[0] < 4:
kwargs.pop('directConnection', None)
return pymongo.MongoClient(**kwargs)
def mongoToolsBin(tool):
'''获取 mongo 客户端工具路径,4.4+ 的 mongodump/mongorestore 由 Database Tools 提供'''
path = getServerDir() + "/bin/" + tool
if os.path.exists(path):
return path
import shutil
return shutil.which(tool) or path
def mongdbClientS():
import pymongo
port = getConfPort()
@@ -196,11 +227,13 @@ def mongdbClientS():
mg_root = pSqliteDb('config').where('id=?', (1,)).getField('mg_root')
if auth == 'disabled':
client = pymongo.MongoClient(host=ip, port=int(port))
client = newMongoClient(host=ip, port=int(port), directConnection=True, serverSelectionTimeoutMS=5000)
else:
# print(auth,mg_root)
# 使用 admin 数据库进行认证,兼容 MongoDB 3.0
client = pymongo.MongoClient(host=ip, port=int(port), username='root', password=mg_root, authSource='admin')
client = newMongoClient(host=ip, port=int(port), directConnection=True,
serverSelectionTimeoutMS=5000,
username='root', password=mg_root, authSource='admin')
return client
def getMongoDBVersion():
@@ -210,7 +243,7 @@ def getMongoDBVersion():
ip = getConfLocalIp()
try:
# 先不使用认证连接
client = pymongo.MongoClient(host=ip, port=int(port), serverSelectionTimeoutMS=5000)
client = newMongoClient(host=ip, port=int(port), directConnection=True, serverSelectionTimeoutMS=5000)
db = client.admin
serverStatus = db.command('serverStatus')
version = serverStatus.get('version', '4.0')
@@ -236,15 +269,19 @@ def mongdbClient():
mg_root = pSqliteDb('config').where('id=?', (1,)).getField('mg_root')
if auth == 'disabled':
client = pymongo.MongoClient(host=ip, port=int(port))
client = newMongoClient(host=ip, port=int(port), directConnection=True, serverSelectionTimeoutMS=5000)
else:
# 根据MongoDB版本选择认证方式
if isMongoDB3x():
# MongoDB 3.x 使用 authSource 指定认证数据库
client = pymongo.MongoClient(host=ip, port=int(port), username='root', password=mg_root, authSource='admin')
client = newMongoClient(host=ip, port=int(port), directConnection=True,
serverSelectionTimeoutMS=5000,
username='root', password=mg_root, authSource='admin')
else:
# MongoDB 4.x+ 默认在 admin 数据库认证
client = pymongo.MongoClient(host=ip, port=int(port), username='root', password=mg_root)
client = newMongoClient(host=ip, port=int(port), directConnection=True,
serverSelectionTimeoutMS=5000,
username='root', password=mg_root)
return client
@@ -317,8 +354,7 @@ def mgOp(method):
def start():
mw.execShell(
'export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/www/server/lib/openssl11/lib')
mw.execShell('export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/www/server/lib/openssl11/lib')
return mgOp('start')
@@ -386,7 +422,7 @@ def initMgRoot(password='',force=0):
if password =='':
mg_pass = mw.getRandomString(8)
else:
mg_pass = password
mg_pass = _sanitize_str(password)
try:
db.command("createUser", "root", pwd=mg_pass, roles=db_all_rules)
@@ -495,32 +531,26 @@ def runInfo():
def runDocInfo():
client = mongdbClient()
db = client.admin
# print(db)
try:
serverStatus = db.command('serverStatus')
db.command('serverStatus')
listDbs = client.list_database_names()
showDbList = []
result = {}
for x in range(len(listDbs)):
mongd = client[listDbs[x]]
stats = mongd.command({"dbstats": 1})
if 'operationTime' in stats:
del stats['operationTime']
if '$clusterTime' in stats:
del stats['$clusterTime']
showDbList.append(stats)
result["dbs"] = showDbList
return mw.getJson(result)
except Exception as e:
return mw.returnJson(False, str(e))
serverStatus = db.command('serverStatus')
listDbs = client.list_database_names()
showDbList = []
result = {}
for x in range(len(listDbs)):
mongd = client[listDbs[x]]
stats = mongd.command({"dbstats": 1})
if 'operationTime' in stats:
del stats['operationTime']
if '$clusterTime' in stats:
del stats['$clusterTime']
showDbList.append(stats)
result["dbs"] = showDbList
return mw.getJson(result)
def runReplInfo():
client = mongdbClient()
db = client.admin
@@ -617,6 +647,28 @@ def getDbList():
return mw.getJson(data)
# return mw.returnJson(True,'ok',data)
def getTableList():
args = getArgs()
db_name = ""
if 'dbname' in args:
db_name = args['dbname']
elif 'name' in args:
db_name = args['name']
if db_name == "":
return mw.returnJson(-1, "table表不能为空")
try:
client = mongdbClient()
data = client[db_name].list_collection_names()
except Exception as e:
return mw.returnJson(-1, str(e))
table_list = []
for i in data:
table_list.append(i)
return mw.returnJson(0, "ok", table_list)
def addDb():
t = status()
if t == 'stop':
@@ -646,8 +698,8 @@ def addDb():
if auth_status:
data_name = args['name']
username = args['db_user']
password = args['password']
username = _sanitize_str(args['db_user'])
password = _sanitize_str(args['password'])
else:
username = data_name
@@ -748,8 +800,8 @@ def setUserPwd(version=''):
if not data[0]:
return data[1]
newpassword = args['password']
username = args['name']
newpassword = _sanitize_str(args['password'])
username = _sanitize_str(args['name'])
uid = args['id']
try:
name = sqlite_db.where('id=?', (uid,)).getField('name')
@@ -853,6 +905,24 @@ def getDbInfo():
return mw.returnJson(True,'ok', result)
def _sanitize_str(val, default=''):
"""清洗 MongoDB 命令中使用的字符串,确保是合法的 UTF-8 且不含空字节。"""
if val is None:
return default
if isinstance(val, bytes):
try:
val = val.decode('utf-8', errors='ignore')
except Exception:
return default
elif not isinstance(val, str):
val = str(val)
# 去掉所有空字节(MongoDB BSON string 禁止 \x00 嵌入)
val = val.replace('\x00', '')
# strip 前后空白与换行
val = val.strip()
return val
def toDbBase(find):
client = mongdbClient()
data_name = find['name']
@@ -860,11 +930,37 @@ def toDbBase(find):
db.zchat.insert_one({})
user_roles = [{'role': 'dbOwner', 'db': data_name}, {'role': 'userAdmin', 'db': data_name}]
username = _sanitize_str(find['username'])
password = _sanitize_str(find['password'])
# 用户名是必须的;密码可空(MongoDB 允许无密码用户)
if not username:
print("syncToDatabases: 跳过空用户名记录 name={}".format(data_name))
return -1
# 密码如果为空字符串,MongoDB 不允许 —— 生成一个临时随机密码
if not password:
password = mw.getRandomString(12)
# 回填到 SQLite
sqlite_db = pSqliteDb('databases')
sqlite_db.where("id=?", (find['id'],)).save('password', (password,))
# 将用户创建在目标数据库中,而不是 admin 数据库
try:
db.command("createUser", find['username'], pwd=find['password'], roles=user_roles)
db.command("createUser", username, pwd=password, roles=user_roles)
except Exception as e:
db.command("updateUser", find['username'], pwd=find['password'], roles=user_roles)
# UserAlreadyExists (code 26) —— 尝试 updateUser
code = getattr(e, 'code', None)
if code == 26:
try:
db.command("updateUser", username, pwd=password, roles=user_roles)
except Exception as e2:
print("syncToDatabases updateUser {} failed: {}".format(username, e2))
return -1
else:
print("syncToDatabases createUser {} failed(code={}): {}".format(username, code, e))
return -1
return 1
def syncToDatabases():
@@ -1236,7 +1332,9 @@ def replClose():
return mw.returnJson(True, '关闭副本同步成功!')
def getDbBackupListFunc(dbname=''):
bkDir = mw.getBackupDir() + '/database'
bkDir = getBackupDir()
if not os.path.isdir(bkDir):
return []
blist = os.listdir(bkDir)
r = []
@@ -1255,7 +1353,7 @@ def getDbBackupList():
return data[1]
r = getDbBackupListFunc(args['name'])
bkDir = mw.getBackupDir() + '/database'
bkDir = getBackupDir()
rr = []
for x in range(0, len(r)):
p = bkDir + '/' + r[x]
@@ -1277,10 +1375,7 @@ def getDbBackupList():
def getDbBackupImportList():
bkImportDir = mw.getBackupDir() + '/mongodb_import'
if not os.path.exists(bkImportDir):
os.mkdir(bkImportDir)
bkImportDir = getImportDir()
blist = os.listdir(bkImportDir)
rr = []
@@ -1320,7 +1415,7 @@ def deleteDbBackup():
if path != "":
full_file = path + "/" + args['filename']
os.remove(full_file)
return mw.returnJson(True, 'ok')
return mw.returnJson(True, '删除成功!')
def setDbBackup():
args = getArgs()
@@ -1328,14 +1423,34 @@ def setDbBackup():
if not data[0]:
return data[1]
scDir = getPluginDir() + '/scripts/backup.py'
cmd = 'python3 ' + scDir + ' database ' + args['name'] + ' 3'
head = "cd "+mw.getPanelDir()
cmd = head +' && . bin/activate && python3 plugins/mongodb/scripts/backup.py database ' + args['name'] + ' 3'
# print(cmd)
os.system(cmd)
return mw.returnJson(True, 'ok')
def getListBson(dbname=''):
bkDir = mw.getBackupDir() + '/mongodb_import/'+dbname
bkDir = getImportDir() + '/' + dbname
if not os.path.isdir(bkDir):
return []
blist = os.listdir(bkDir)
r = []
bname = 'bson'
blen = len(bname)
for x in blist:
if x.endswith(bname):
r.append(x)
# if x.endswith('json'):
# r.append(x)
return r
def getListBsonByDatabase(dbname=''):
bkDir = getBackupDir() + '/' + dbname
if not os.path.isdir(bkDir):
return []
blist = os.listdir(bkDir)
r = []
@@ -1359,8 +1474,7 @@ def importDbExternal():
file = args['file']
name = args['name']
import_dir = mw.getBackupDir() + '/mongodb_import/'
mg_root = pSqliteDb('config').where('id=?', (1,)).getField('mg_root')
import_dir = getImportDir() + '/'
port = getConfPort()
file_path = import_dir + file
@@ -1393,7 +1507,7 @@ def importDbExternal():
bson_list = getListBson(name)
# print(bson_list)
for x in bson_list:
cmd = getServerDir() + "/bin/mongorestore "+uoption+" --port "+str(port)+" --dir "+file_dir+'/'+x
cmd = mongoToolsBin('mongorestore') + " "+uoption+" --port "+str(port)+" --dir "+file_dir+'/'+x
# print(cmd)
rdata = mw.execShell(cmd)
# print(data)
@@ -1407,6 +1521,69 @@ def importDbExternal():
return mw.returnJson(True, 'ok')
def importDbExternalProgress():
args = getArgs()
data = checkArgs(args, ['file', 'name'])
if not data[0]:
return data[1]
file = args['file']
name = args['name']
cmd = 'cd '+mw.getServerDir()+'/mdserver-web && . bin/activate && '
cmd += 'python3 '+mw.getServerDir()+'/mdserver-web/plugins/mongodb/index.py import_db_external_progress_bar {"file":"'+file+'","name":"'+name+'"}'
return mw.returnJson(True, 'ok',cmd)
def importDbExternalProgressBar():
args = getArgs()
data = checkArgs(args, ['file', 'name'])
if not data[0]:
return data[1]
file = args['file']
name = args['name']
import_dir = mw.getFatherDir() + '/backup/mongodb_import/'
port = getConfPort()
file_path = import_dir + file
if not os.path.exists(file_path):
return mw.returnJson(False, '文件突然消失?')
exts = ['sql', 'gz', 'zip']
ext = mw.getFileSuffix(file)
if ext not in exts:
return mw.returnJson(False, '导入数据库格式不对!')
file_dir = import_dir+name
if not os.path.exists(file_dir):
mw.execShell("mkdir -p "+file_dir)
auth = getConfAuth()
mg_root = pSqliteDb('config').where('id=?', (1,)).getField('mg_root')
uoption = ''
if auth != 'disabled':
uoption =' --authenticationDatabase admin -u root -p '+mg_root
file_tgz = import_dir+file
if os.path.exists(file_tgz):
cmd = 'cd ' + file_dir + ' && tar -xzvf ' + file_tgz + " -C "+file_dir
mw.execShell(cmd)
bson_list = getListBson(name)
for x in bson_list:
# mehotd 1
cmd = mongoToolsBin('mongorestore') + " "+uoption+" --port "+str(port)+" --dir "+file_dir+'/'+x
os.system(cmd)
# method2
# cmd = mongoToolsBin('mongorestore') + " "+uoption+" --port "+str(port) + " --archive --db "+name + " --collection " + x.strip(".bson")
# cmd_progress_bar = "pv -t -p " + file_dir+"/"+x + '|'+ cmd
# print(cmd_progress_bar)
# os.system(mysql_cmd_progress_bar)
if os.path.exists(file_dir):
del_cmd = "rm -rf "+file_dir
mw.execShell(del_cmd)
return ""
def importDbBackup():
args = getArgs()
@@ -1418,7 +1595,6 @@ def importDbBackup():
name = args['name']
port = getConfPort()
file_tgz = mw.getBackupDir() + '/database/' + file
file_dir = mw.getBackupDir() + '/database/' + file.replace('.tar.gz','')
@@ -1437,11 +1613,9 @@ def importDbBackup():
if auth != 'disabled':
uoption =' -u root -p '+mg_root
cmd = getServerDir() + "/bin/mongorestore "+uoption+" --port "+str(port)+" --dir "+file_dir
cmd = mongoToolsBin('mongorestore') + " "+uoption+" --port "+str(port)+" --dir "+file_dir
# print(cmd)
mw.execShell(cmd)
# 删除文件
if os.path.exists(file_dir):
del_cmd = "rm -rf "+file_dir
@@ -1449,6 +1623,66 @@ def importDbBackup():
return mw.returnJson(True, 'ok')
def importDbBackupProgress():
args = getArgs()
data = checkArgs(args, ['file', 'name'])
if not data[0]:
return data[1]
file = args['file']
name = args['name']
cmd = 'cd '+mw.getServerDir()+'/mdserver-web && . bin/activate && '
cmd += 'python3 '+mw.getServerDir()+'/mdserver-web/plugins/mongodb/index.py import_db_backup_progress_bar {"file":"'+file+'","name":"'+name+'"}'
return mw.returnJson(True, 'ok',cmd)
# return mw.returnJson(True, 'ok')
def importDbBackupProgressBar():
args = getArgs()
data = checkArgs(args, ['file', 'name'])
if not data[0]:
return data[1]
file = args['file']
name = args['name']
import_dir = mw.getFatherDir() + '/backup/database/mongodb/'
port = getConfPort()
file_path = import_dir + file
if not os.path.exists(file_path):
return mw.returnJson(False, '文件突然消失?')
exts = ['sql', 'gz', 'zip']
ext = mw.getFileSuffix(file)
if ext not in exts:
return mw.returnJson(False, '导入数据库格式不对!')
file_dir = import_dir+name
if not os.path.exists(file_dir):
mw.execShell("mkdir -p "+file_dir)
auth = getConfAuth()
mg_root = pSqliteDb('config').where('id=?', (1,)).getField('mg_root')
uoption = ''
if auth != 'disabled':
uoption =' --authenticationDatabase admin -u root -p '+mg_root
file_tgz = import_dir+file
if os.path.exists(file_tgz):
cmd = 'cd ' + file_dir + ' && tar -xzvf ' + file_tgz + " -C "+file_dir
mw.execShell(cmd)
bson_list = getListBsonByDatabase(name)
for x in bson_list:
# mehotd 1
cmd = mongoToolsBin('mongorestore') + " "+uoption+" --port "+str(port)+" --dir "+file_dir+'/'+x
os.system(cmd)
if os.path.exists(file_dir):
del_cmd = "rm -rf "+file_dir
mw.execShell(del_cmd)
return ""
def testData():
'''
cd /www/server/mdserver-web && . bin/activate && python3 /www/server/mdserver-web/plugins/mongodb/index.py test_data
@@ -1608,6 +1842,9 @@ def installPreInspection(version):
def uninstallPreInspection(version):
stop()
# if mw.isDebugMode():
# return 'ok'
from utils.plugin import plugin as MwPlugin
MwPlugin.instance().removeIndex(getPluginName(), version)
@@ -1660,6 +1897,8 @@ if __name__ == "__main__":
print(rootPwd())
elif func == 'get_db_list':
print(getDbList())
elif func == 'get_table_list':
print(getTableList())
elif func == 'add_db':
print(addDb())
elif func == 'del_db':
@@ -1706,8 +1945,16 @@ if __name__ == "__main__":
print(setDbBackup())
elif func == 'import_db_external':
print(importDbExternal())
elif func == 'import_db_external_progress':
print(importDbExternalProgress())
elif func == 'import_db_external_progress_bar':
print(importDbExternalProgressBar())
elif func == 'import_db_backup':
print(importDbBackup())
elif func == 'import_db_backup_progress':
print(importDbBackupProgress())
elif func == 'import_db_backup_progress_bar':
print(importDbBackupProgressBar())
elif func == 'run_log':
print(runLog())
elif func == 'test':

View File

@@ -7,7 +7,7 @@
"shell": "install.sh",
"install_pre_inspection":true,
"uninstall_pre_inspection":true,
"versions":["3.0","4.4","5.0","6.0","7.0","8.0","8.2"],
"versions":["3.0","4.4","5.0","6.0","7.0","8.0","8.2","9.0"],
"tip": "soft",
"checks": "server/mongodb",
"path": "server/mongodb",

View File

@@ -6,7 +6,7 @@ export PATH
# cd /Users/midoks/Desktop/mwdev/server/mdserver-web/plugins/mongodb && /bin/bash install.sh install 7.0
# cd /www/server/mdserver-web/plugins/mongodb && /bin/bash install.sh install 7.0
# cd /www/server/mdserver-web/plugins/mongodb && /bin/bash install.sh install 8.0
# cd /www/server/mdserver-web/plugins/mongodb && /bin/bash install.sh install 9.0
# cd /www/server/mdserver-web/plugins/mongodb && /bin/bash install.sh install 3.0
# cd /www/server/mdserver-web && python3 /www/server/mdserver-web/plugins/mongodb/index.py start

View File

@@ -1033,12 +1033,13 @@ function setBackup(db_name){
var layerIndex = layer.open({
type: 1,
title: "数据库[MongoDB]备份详情",
area: ['600px', '280px'],
area: ['700px', '280px'],
closeBtn: 1,
shadeClose: false,
content: '<div class="pd15">\
<div class="db_list">\
<button id="btn_backup" class="btn btn-success btn-sm" type="button">备份</button>\
<button id="btn_backup_reload" class="btn btn-success btn-sm" type="button">刷新</button>\
<button id="btn_local_import" class="btn btn-success btn-sm" type="button">外部导入</button>\
</div >\
<div class="divtable">\
@@ -1070,6 +1071,10 @@ function setBackup(db_name){
setLocalImport(db_name);
});
$('#btn_backup_reload').click(function(){
setBackupReq(db_name);
});
setBackupReq(db_name);
},
});
@@ -1086,6 +1091,7 @@ function setBackupReq(db_name, obj){
<td><span> ' + rdata.data[i]['time'] + '</span></td>\
<td style="text-align: right;">\
<a class="btlink" onclick="importBackup(\'' + rdata.data[i]['name'] + '\',\'' +db_name+ '\')">导入</a> | \
<a class="btlink" onclick="importBackupProgress(\'' + rdata.data[i]['name'] + '\',\'' +db_name+ '\')">导入进度</a> | \
<a class="btlink" onclick="downloadBackup(\'' + rdata.data[i]['file'] + '\')">下载</a> | \
<a class="btlink" onclick="delBackup(\'' + rdata.data[i]['name'] + '\',\'' +db_name+ '\')">删除</a>\
</td>\
@@ -1100,7 +1106,7 @@ function delBackup(filename, name, path){
path = "";
}
mgPost('delete_db_backup','',{filename:filename,path:path},function(){
layer.msg('执行成功!');
layer.msg(rdata.msg, { icon: rdata.status ? 1 : 2 });
setTimeout(function(){
setBackupReq(name);
},2000);
@@ -1117,8 +1123,32 @@ function importBackup(file,name){
});
}
function setLocalImport(db_name){
function importBackupProgress(file,name){
mgPost('import_db_backup_progress', '',{file:file,name:name}, function(data){
var rdata = $.parseJSON(data.data);
layer.open({
title: "手动导入命令CMD【显示进度】",
area: ['600px', '180px'],
type:1,
closeBtn: 1,
shadeClose: false,
btn:["复制","取消"],
content: '<div class="pd15">\
<div class="divtable">\
<pre class="layui-code">'+rdata.data+'</pre>\
</div>\
</div>',
success:function(){
copyText(rdata.data);
},
yes:function(){
copyText(rdata.data);
}
});
});
}
function setLocalImport(db_name){
//上传文件
function uploadDbFiles(upload_dir){
var up_db = layer.open({
@@ -1172,6 +1202,7 @@ function setLocalImport(db_name){
<td><span> ' + file_list[i]['time'] + '</span></td>\
<td style="text-align: right;">\
<a class="btlink" onclick="importDbExternal(\'' + file_list[i]['name'] + '\',\'' +db_name+ '\')">导入</a> | \
<a class="btlink" onclick="importDbExternalProgress(\'' + file_list[i]['name'] + '\',\'' +db_name+ '\')">导入进度</a> | \
<a class="btlink del" index="'+i+'">删除</a>\
</td>\
</tr>';
@@ -1195,7 +1226,7 @@ function setLocalImport(db_name){
var layerIndex = layer.open({
type: 1,
title: "从文件导入数据",
area: ['600px', '380px'],
area: ['700px', '380px'],
closeBtn: 1,
shadeClose: false,
content: '<div class="pd15">\
@@ -1229,7 +1260,6 @@ function setLocalImport(db_name){
var upload_dir = $('input[name="upload_dir"]').val();
uploadDbFiles(upload_dir);
});
getList();
},
});
@@ -1241,6 +1271,32 @@ function importDbExternal(file,name){
});
}
function importDbExternalProgress(file,name){
mgPost('import_db_external_progress', '',{file:file,name:name}, function(data){
var rdata = $.parseJSON(data.data);
layer.open({
title: "手动导入命令CMD【显示进度】",
area: ['600px', '180px'],
type:1,
closeBtn: 1,
shadeClose: false,
btn:["复制","取消"],
content: '<div class="pd15">\
<div class="divtable">\
<pre class="layui-code">'+rdata.data+'</pre>\
</div>\
</div>',
success:function(){
copyText(rdata.data);
},
yes:function(){
copyText(rdata.data);
}
});
});
}
function otherFunc(){
var con = '<p class="conf_p" style="text-align:center;">\
<button class="btn btn-default btn-sm" onclick="cronAddCheck()">添加检查任务</button> \

View File

@@ -11,9 +11,13 @@ import yaml
if sys.platform != 'darwin':
os.chdir('/www/server/mdserver-web')
base_dir = os.getcwd()
else:
# 开发环境按脚本位置向上定位项目根(scripts -> mongodb -> plugins -> 根目录)
script_dir = os.path.dirname(os.path.abspath(__file__))
base_dir = os.path.dirname(os.path.dirname(os.path.dirname(script_dir)))
web_dir = os.getcwd() + "/web"
web_dir = base_dir + "/web"
if os.path.exists(web_dir):
sys.path.append(web_dir)
os.chdir(web_dir)
@@ -134,6 +138,8 @@ class backupTools:
def getDbBackupList(self,dbname=''):
bkDir = mw.getFatherDir() + '/backup/database'
if not os.path.isdir(bkDir):
return []
blist = os.listdir(bkDir)
r = []
@@ -143,9 +149,21 @@ class backupTools:
fbstr = x[0:blen]
if fbstr == bname:
r.append(x)
r.sort()
return r
def backupDatabase(self, name, count):
def backupDatabase(self, params, count):
params_args = params.split("@")
name = params_args[0]
table_name = ''
if len(params_args) > 1:
table_name = params_args[1]
backup_bgname = name
if table_name != '':
backup_bgname = name+'@'+table_name
db_path = mw.getServerDir() + '/mongodb'
db_name = 'mongodb'
name = mw.M('databases').dbPos(db_path, db_name).where('name=?', (name,)).getField('name')
@@ -155,16 +173,15 @@ class backupTools:
endDate = time.strftime('%Y/%m/%d %X', time.localtime())
log = "数据库[" + name + "]不存在!"
print("★[" + endDate + "] " + log)
print(
"----------------------------------------------------------------------------")
print("----------------------------------------------------------------------------")
return
backup_path = mw.getBackupDir() + '/database'
backup_path = mw.getBackupDir() + '/database/mongodb'
if not os.path.exists(backup_path):
mw.execShell("mkdir -p " + backup_path)
time_now = time.strftime('%Y%m%d_%H%M%S', time.localtime())
backup_name = "mongodb_" + name + "_" + time_now + ".tar.gz"
backup_name = "mongodb_" + backup_bgname + "_" + time_now + ".tar.gz"
filename = backup_path + "/"+backup_name
port = getConfPort()
@@ -174,7 +191,15 @@ class backupTools:
if auth != 'disabled':
uoption =' --authenticationDatabase admin -u root -p '+mg_root
cmd = db_path + "/bin/mongodump "+uoption+" --port "+str(port)+" -d "+name+" -o "+backup_path
# 4.4+ 的 mongodump 由 Database Tools 提供,不在 server/bin 目录
mongodump_bin = db_path + "/bin/mongodump"
if not os.path.exists(mongodump_bin):
import shutil
mongodump_bin = shutil.which('mongodump') or mongodump_bin
cmd = mongodump_bin + uoption+" --port "+str(port)+" -d "+name+" -o "+backup_path
if table_name != "":
cmd += " -c " + table_name
# print(cmd)
mw.execShell(cmd)
cmd_gz = "cd "+backup_path+"/"+name+" && tar -zcvf "+filename + " ./"
@@ -207,7 +232,7 @@ class backupTools:
for backup in backups:
mw.execShell("rm -f " + backup_path + "/"+backup)
num -= 1
print("|---已清理过期备份文件:" + backup)
print("|---已清理过期文件:" + backup)
if num < 1:
break

View File

@@ -0,0 +1,107 @@
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin
export PATH
curPath=`pwd`
rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
VERSION=9.0.4
SYS_ARCH=`arch`
SYS_VERSION_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}'`
SYS_NAME=${SYS_VERSION_ID/./}
SYS_NAME_LEN=`echo "$SYS_NAME" | wc -L`
if [ "$SYS_NAME_LEN" = "1" ];then
SYS_NAME=${SYS_NAME}0
fi
if [ "$SYS_ARCH" = "aarch64" ];then
if [ "$SYS_NAME" -gt "90" ];then
SYS_NAME="90"
fi
if [ "$SYS_NAME" -lt "82" ];then
SYS_NAME="82"
fi
else
if [ "$SYS_NAME" -gt "90" ];then
SYS_NAME="90"
fi
if [ "$SYS_NAME" -lt "70" ];then
SYS_NAME="70"
fi
fi
MG_DIR=$serverPath/source/mongodb
mkdir -p $MG_DIR
FILE_NAME=mongodb-linux-${SYS_ARCH}-rhel${SYS_NAME}-${VERSION}
FILE_NAME_TGZ=${FILE_NAME}.tgz
if [ ! -f $MG_DIR/${FILE_NAME_TGZ} ]; then
wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/linux/${FILE_NAME_TGZ}
echo "wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/linux/${FILE_NAME_TGZ}"
fi
if [ ! -d $MG_DIR/${FILE_NAME} ];then
cd $MG_DIR && tar -zxvf ${FILE_NAME_TGZ}
fi
if [ ! -f $serverPath/mongodb/bin/mongod ];then
mkdir -p $serverPath/mongodb
cd $MG_DIR/${FILE_NAME} && cp -rf ./bin $serverPath/mongodb
fi
cd ${MG_DIR} && rm -rf ${MG_DIR}/${FILE_NAME}
#--------------- mongosh tool install ------------------ #
TOOL_VERSION=2.2.5
TOOL_FILE_NAME=mongosh-${TOOL_VERSION}-linux-x64
if [ "aarch64" = ${SYS_ARCH} ];then
TOOL_FILE_NAME=mongosh-${TOOL_VERSION}-linux-arm64
fi
TOOL_FILE_NAME_TGZ=${TOOL_FILE_NAME}.tgz
if [ ! -f $MG_DIR/${TOOL_FILE_NAME_TGZ} ]; then
wget --no-check-certificate -O $MG_DIR/${TOOL_FILE_NAME_TGZ} https://downloads.mongodb.com/compass/${TOOL_FILE_NAME_TGZ}
echo "wget --no-check-certificate -O $MG_DIR/${TOOL_FILE_NAME_TGZ} https://downloads.mongodb.com/compass/${TOOL_FILE_NAME_TGZ}"
fi
if [ ! -d $MG_DIR/${TOOL_FILE_NAME_TGZ} ];then
cd $MG_DIR && tar -zxvf ${TOOL_FILE_NAME_TGZ}
fi
cd ${MG_DIR}/${TOOL_FILE_NAME} && cp -rf ./bin $serverPath/mongodb
cd ${MG_DIR} && rm -rf ${MG_DIR}/${TOOL_FILE_NAME}
# https://fastdl.mongodb.org/tools/db/mongodb-database-tools-rhel90-aarch64-100.9.4.tgz
# https://fastdl.mongodb.org/tools/db/mongodb-database-tools-rhel90-x86_64-100.9.4.tgz
# https://fastdl.mongodb.org/tools/db/mongodb-database-tools-rhel83-s390x-100.9.4.tgz
#--------------- mongodb database install ------------------ #
TOOL_VERSION=100.9.4
TOOL_FILE_NAME=mongodb-database-tools-rhel${SYS_NAME}-x86_64-${TOOL_VERSION}
if [ "aarch64" = ${SYS_ARCH} ];then
TOOL_FILE_NAME=mongodb-database-tools-rhel${SYS_NAME}-aarch64-${TOOL_VERSION}
fi
if [ "arm64" = ${SYS_ARCH} ];then
TOOL_FILE_NAME=mongodb-database-tools-rhel${SYS_NAME}-arm64-${TOOL_VERSION}
fi
TOOL_FILE_NAME_TGZ=${TOOL_FILE_NAME}.tgz
if [ ! -f $MG_DIR/${TOOL_FILE_NAME_TGZ} ]; then
wget --no-check-certificate -O $MG_DIR/${TOOL_FILE_NAME_TGZ} https://fastdl.mongodb.org/tools/db/${TOOL_FILE_NAME_TGZ}
fi
if [ ! -d $MG_DIR/${TOOL_FILE_NAME_TGZ} ];then
cd $MG_DIR && tar -zxvf ${TOOL_FILE_NAME_TGZ}
fi
cd ${MG_DIR}/${TOOL_FILE_NAME} && cp -rf ./bin $serverPath/mongodb
cd ${MG_DIR} && rm -rf ${MG_DIR}/${TOOL_FILE_NAME}

View File

@@ -0,0 +1,84 @@
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin
export PATH
curPath=`pwd`
rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
VERSION=9.0.4
SYS_ARCH=`arch`
SYS_VERSION_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}'`
SYS_NAME=${SYS_VERSION_ID/./}
SYS_NAME="12"
FILE_NAME=mongodb-linux-${SYS_ARCH}-debian${SYS_NAME}-${VERSION}
FILE_NAME_TGZ=${FILE_NAME}.tgz
MG_DIR=$serverPath/source/mongodb
mkdir -p $MG_DIR
if [ ! -f $MG_DIR/${FILE_NAME_TGZ} ]; then
wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/linux/${FILE_NAME_TGZ}
echo "wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/linux/${FILE_NAME_TGZ}"
fi
if [ ! -d $MG_DIR/${FILE_NAME_TGZ} ];then
cd $MG_DIR && tar -zxvf ${FILE_NAME_TGZ}
fi
if [ ! -f $serverPath/mongodb/bin/mongod ];then
mkdir -p $serverPath/mongodb
cd $MG_DIR/${FILE_NAME} && cp -rf ./bin $serverPath/mongodb
fi
cd ${MG_DIR} && rm -rf ${MG_DIR}/${FILE_NAME}
#--------------- mongosh tool install ------------------ #
TOOL_VERSION=2.2.5
TOOL_FILE_NAME=mongosh-${TOOL_VERSION}-linux-x64
if [ "aarch64" = ${SYS_ARCH} ];then
TOOL_FILE_NAME=mongosh-${TOOL_VERSION}-linux-arm64
fi
TOOL_FILE_NAME_TGZ=${TOOL_FILE_NAME}.tgz
if [ ! -f $MG_DIR/${TOOL_FILE_NAME_TGZ} ]; then
wget --no-check-certificate -O $MG_DIR/${TOOL_FILE_NAME_TGZ} https://downloads.mongodb.com/compass/${TOOL_FILE_NAME_TGZ}
echo "wget --no-check-certificate -O $MG_DIR/${TOOL_FILE_NAME_TGZ} https://downloads.mongodb.com/compass/${TOOL_FILE_NAME_TGZ}"
fi
if [ ! -d $MG_DIR/${TOOL_FILE_NAME_TGZ} ];then
cd $MG_DIR && tar -zxvf ${TOOL_FILE_NAME_TGZ}
fi
cd ${MG_DIR}/${TOOL_FILE_NAME} && cp -rf ./bin $serverPath/mongodb
cd ${MG_DIR} && rm -rf ${MG_DIR}/${TOOL_FILE_NAME}
#--------------- mongodb database install ------------------ #
TOOL_VERSION=100.9.4
TOOL_FILE_NAME=mongodb-database-tools-debian${SYS_NAME}-x86_64-${TOOL_VERSION}
if [ "aarch64" = ${SYS_ARCH} ];then
TOOL_FILE_NAME=mongodb-database-tools-debian${SYS_NAME}-arm64-${TOOL_VERSION}
fi
if [ "arm64" = ${SYS_ARCH} ];then
TOOL_FILE_NAME=mongodb-database-tools-debian${SYS_NAME}-arm64-${TOOL_VERSION}
fi
TOOL_FILE_NAME_TGZ=${TOOL_FILE_NAME}.tgz
if [ ! -f $MG_DIR/${TOOL_FILE_NAME_TGZ} ]; then
wget --no-check-certificate -O $MG_DIR/${TOOL_FILE_NAME_TGZ} https://fastdl.mongodb.org/tools/db/${TOOL_FILE_NAME_TGZ}
fi
if [ ! -d $MG_DIR/${TOOL_FILE_NAME_TGZ} ];then
cd $MG_DIR && tar -zxvf ${TOOL_FILE_NAME_TGZ}
fi
cd ${MG_DIR}/${TOOL_FILE_NAME} && cp -rf ./bin $serverPath/mongodb
cd ${MG_DIR} && rm -rf ${MG_DIR}/${TOOL_FILE_NAME}

View File

@@ -0,0 +1,107 @@
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin
export PATH
curPath=`pwd`
rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
VERSION=9.0.4
SYS_ARCH=`arch`
SYS_VERSION_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}'`
SYS_NAME=${SYS_VERSION_ID/./}
SYS_NAME_LEN=`echo "$SYS_NAME" | wc -L`
if [ "$SYS_NAME_LEN" = "1" ];then
SYS_NAME=${SYS_NAME}0
fi
if [ "$SYS_ARCH" = "aarch64" ];then
if [ "$SYS_NAME" -gt "90" ];then
SYS_NAME="90"
fi
if [ "$SYS_NAME" -lt "82" ];then
SYS_NAME="82"
fi
else
if [ "$SYS_NAME" -gt "90" ];then
SYS_NAME="90"
fi
if [ "$SYS_NAME" -lt "70" ];then
SYS_NAME="70"
fi
fi
MG_DIR=$serverPath/source/mongodb
mkdir -p $MG_DIR
FILE_NAME=mongodb-linux-${SYS_ARCH}-rhel${SYS_NAME}-${VERSION}
FILE_NAME_TGZ=${FILE_NAME}.tgz
if [ ! -f $MG_DIR/${FILE_NAME_TGZ} ]; then
wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/linux/${FILE_NAME_TGZ}
echo "wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/linux/${FILE_NAME_TGZ}"
fi
if [ ! -d $MG_DIR/${FILE_NAME} ];then
cd $MG_DIR && tar -zxvf ${FILE_NAME_TGZ}
fi
if [ ! -f $serverPath/mongodb/bin/mongod ];then
mkdir -p $serverPath/mongodb
cd $MG_DIR/${FILE_NAME} && cp -rf ./bin $serverPath/mongodb
fi
cd ${MG_DIR} && rm -rf ${MG_DIR}/${FILE_NAME}
#--------------- mongosh tool install ------------------ #
TOOL_VERSION=2.2.5
TOOL_FILE_NAME=mongosh-${TOOL_VERSION}-linux-x64
if [ "aarch64" = ${SYS_ARCH} ];then
TOOL_FILE_NAME=mongosh-${TOOL_VERSION}-linux-arm64
fi
TOOL_FILE_NAME_TGZ=${TOOL_FILE_NAME}.tgz
if [ ! -f $MG_DIR/${TOOL_FILE_NAME_TGZ} ]; then
wget --no-check-certificate -O $MG_DIR/${TOOL_FILE_NAME_TGZ} https://downloads.mongodb.com/compass/${TOOL_FILE_NAME_TGZ}
echo "wget --no-check-certificate -O $MG_DIR/${TOOL_FILE_NAME_TGZ} https://downloads.mongodb.com/compass/${TOOL_FILE_NAME_TGZ}"
fi
if [ ! -d $MG_DIR/${TOOL_FILE_NAME_TGZ} ];then
cd $MG_DIR && tar -zxvf ${TOOL_FILE_NAME_TGZ}
fi
cd ${MG_DIR}/${TOOL_FILE_NAME} && cp -rf ./bin $serverPath/mongodb
cd ${MG_DIR} && rm -rf ${MG_DIR}/${TOOL_FILE_NAME}
# https://fastdl.mongodb.org/tools/db/mongodb-database-tools-rhel90-aarch64-100.9.4.tgz
# https://fastdl.mongodb.org/tools/db/mongodb-database-tools-rhel90-x86_64-100.9.4.tgz
# https://fastdl.mongodb.org/tools/db/mongodb-database-tools-rhel83-s390x-100.9.4.tgz
#--------------- mongodb database install ------------------ #
TOOL_VERSION=100.9.4
TOOL_FILE_NAME=mongodb-database-tools-rhel${SYS_NAME}-x86_64-${TOOL_VERSION}
if [ "aarch64" = ${SYS_ARCH} ];then
TOOL_FILE_NAME=mongodb-database-tools-rhel${SYS_NAME}-aarch64-${TOOL_VERSION}
fi
if [ "arm64" = ${SYS_ARCH} ];then
TOOL_FILE_NAME=mongodb-database-tools-rhel${SYS_NAME}-arm64-${TOOL_VERSION}
fi
TOOL_FILE_NAME_TGZ=${TOOL_FILE_NAME}.tgz
if [ ! -f $MG_DIR/${TOOL_FILE_NAME_TGZ} ]; then
wget --no-check-certificate -O $MG_DIR/${TOOL_FILE_NAME_TGZ} https://fastdl.mongodb.org/tools/db/${TOOL_FILE_NAME_TGZ}
fi
if [ ! -d $MG_DIR/${TOOL_FILE_NAME_TGZ} ];then
cd $MG_DIR && tar -zxvf ${TOOL_FILE_NAME_TGZ}
fi
cd ${MG_DIR}/${TOOL_FILE_NAME} && cp -rf ./bin $serverPath/mongodb
cd ${MG_DIR} && rm -rf ${MG_DIR}/${TOOL_FILE_NAME}

View File

@@ -0,0 +1,86 @@
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin
export PATH
curPath=`pwd`
rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
SYS_ARCH=`arch`
VERSION=9.0.4
MG_DIR=$serverPath/source/mongodb
mkdir -p $MG_DIR
# https://fastdl.mongodb.org/osx/mongodb-macos-arm64-8.0.3.tgz
FILE_NAME=mongodb-macos-x86_64-${VERSION}
if [ "arm64" = "${SYS_ARCH}" ];then
FILE_NAME=mongodb-macos-arm64-${VERSION}
fi
FILE_NAME_TGZ=${FILE_NAME}.tgz
if [ ! -f $MG_DIR/${FILE_NAME_TGZ} ]; then
wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/osx/${FILE_NAME_TGZ}
echo "wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/osx/${FILE_NAME_TGZ}"
fi
if [ ! -d $MG_DIR/${FILE_NAME} ];then
cd $MG_DIR && tar -zxvf ${FILE_NAME_TGZ}
fi
if [ ! -f $serverPath/mongodb/bin/mongod ];then
mkdir -p $serverPath/mongodb
cd $MG_DIR/${FILE_NAME} && cp -rf ./bin $serverPath/mongodb
fi
# https://downloads.mongodb.com/compass/mongosh-2.2.5-darwin-x64.zip
# https://downloads.mongodb.com/compass/mongosh-2.2.5-darwin-arm64.zip
#--------------- mongosh tool install ------------------ #
TOOL_VERSION=2.2.5
TOOL_FILE_NAME=mongosh-${TOOL_VERSION}-darwin-x64
if [ "aarch64" = ${SYS_ARCH} ];then
TOOL_FILE_NAME=mongosh-${TOOL_VERSION}-darwin-arm64
fi
if [ "arm64" = ${SYS_ARCH} ];then
TOOL_FILE_NAME=mongosh-${TOOL_VERSION}-darwin-arm64
fi
TOOL_FILE_NAME_TGZ=${TOOL_FILE_NAME}.zip
if [ ! -f $MG_DIR/${TOOL_FILE_NAME_TGZ} ]; then
wget --no-check-certificate -O $MG_DIR/${TOOL_FILE_NAME_TGZ} https://downloads.mongodb.com/compass/${TOOL_FILE_NAME_TGZ}
echo "wget --no-check-certificate -O $MG_DIR/${TOOL_FILE_NAME_TGZ} https://downloads.mongodb.com/compass/${TOOL_FILE_NAME_TGZ}"
fi
if [ ! -d $MG_DIR/${TOOL_FILE_NAME_TGZ} ];then
cd $MG_DIR && unzip ${TOOL_FILE_NAME_TGZ}
fi
cd ${MG_DIR}/${TOOL_FILE_NAME} && cp -rf ./bin $serverPath/mongodb
cd ${MG_DIR} && rm -rf ${MG_DIR}/${TOOL_FILE_NAME}
# https://fastdl.mongodb.org/tools/db/mongodb-database-tools-macos-arm64-100.9.4.zip
TOOL_VERSION=100.9.4
TOOL_FILE_NAME=mongodb-database-tools-macos-x86_64-${TOOL_VERSION}
if [ "aarch64" = ${SYS_ARCH} ];then
TOOL_FILE_NAME=mongodb-database-tools-macos-arm64-${TOOL_VERSION}
fi
if [ "arm64" = ${SYS_ARCH} ];then
TOOL_FILE_NAME=mongodb-database-tools-macos-arm64-${TOOL_VERSION}
fi
TOOL_FILE_NAME_TGZ=${TOOL_FILE_NAME}.zip
if [ ! -f $MG_DIR/${TOOL_FILE_NAME_TGZ} ]; then
wget --no-check-certificate -O $MG_DIR/${TOOL_FILE_NAME_TGZ} https://fastdl.mongodb.org/tools/db/${TOOL_FILE_NAME_TGZ}
echo "wget --no-check-certificate -O $MG_DIR/${TOOL_FILE_NAME_TGZ} https://fastdl.mongodb.org/tools/db/${TOOL_FILE_NAME_TGZ}"
fi
if [ ! -d $MG_DIR/${TOOL_FILE_NAME_TGZ} ];then
cd $MG_DIR && unzip ${TOOL_FILE_NAME_TGZ}
fi
cd ${MG_DIR}/${TOOL_FILE_NAME} && cp -rf ./bin $serverPath/mongodb
cd ${MG_DIR} && rm -rf ${MG_DIR}/${TOOL_FILE_NAME}

View File

@@ -0,0 +1,94 @@
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin
export PATH
curPath=`pwd`
rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
VERSION=9.0.4
SYS_ARCH=`arch`
SYS_VERSION_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}' | awk -F . '{print $1}'`
SYS_NAME="15"
if [ "$SYS_VERSION_ID" -gt "15" ];then
SYS_NAME="15"
fi
if [ "$SYS_NAME" -lt "12" ];then
SYS_NAME="12"
fi
# https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-suse15-4.4.23.tgz
# https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-suse12-4.4.23.tgz
MG_DIR=$serverPath/source/mongodb
mkdir -p $MG_DIR
FILE_NAME=mongodb-linux-${SYS_ARCH}-suse${SYS_NAME}-${VERSION}
FILE_NAME_TGZ=${FILE_NAME}.tgz
if [ ! -f $MG_DIR/${FILE_NAME_TGZ} ]; then
wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/linux/${FILE_NAME_TGZ}
echo "wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/linux/${FILE_NAME_TGZ}"
fi
if [ ! -d $MG_DIR/${FILE_NAME} ];then
cd $MG_DIR && tar -zxvf ${FILE_NAME_TGZ}
fi
if [ ! -f $serverPath/mongodb/bin/mongod ];then
mkdir -p $serverPath/mongodb
cd $MG_DIR/${FILE_NAME} && cp -rf ./bin $serverPath/mongodb
fi
cd ${MG_DIR} && rm -rf ${MG_DIR}/${FILE_NAME}
#--------------- mongosh tool install ------------------ #
TOOL_VERSION=2.2.5
TOOL_FILE_NAME=mongosh-${TOOL_VERSION}-linux-x64
if [ "aarch64" = ${SYS_ARCH} ];then
TOOL_FILE_NAME=mongosh-${TOOL_VERSION}-linux-arm64
fi
TOOL_FILE_NAME_TGZ=${TOOL_FILE_NAME}.tgz
if [ ! -f $MG_DIR/${TOOL_FILE_NAME_TGZ} ]; then
wget --no-check-certificate -O $MG_DIR/${TOOL_FILE_NAME_TGZ} https://downloads.mongodb.com/compass/${TOOL_FILE_NAME_TGZ}
echo "wget --no-check-certificate -O $MG_DIR/${TOOL_FILE_NAME_TGZ} https://downloads.mongodb.com/compass/${TOOL_FILE_NAME_TGZ}"
fi
if [ ! -d $MG_DIR/${TOOL_FILE_NAME_TGZ} ];then
cd $MG_DIR && tar -zxvf ${TOOL_FILE_NAME_TGZ}
fi
cd ${MG_DIR}/${TOOL_FILE_NAME} && cp -rf ./bin $serverPath/mongodb
cd ${MG_DIR} && rm -rf ${MG_DIR}/${TOOL_FILE_NAME}
# https://fastdl.mongodb.org/tools/db/mongodb-database-tools-suse12-x86_64-100.9.4.tgz
#--------------- mongodb database install ------------------ #
TOOL_VERSION=100.9.4
TOOL_FILE_NAME=mongodb-database-tools-suse${SYS_NAME}-x86_64-${TOOL_VERSION}
if [ "aarch64" = ${SYS_ARCH} ];then
TOOL_FILE_NAME=mongodb-database-tools-suse${SYS_NAME}-arm64-${TOOL_VERSION}
fi
if [ "arm64" = ${SYS_ARCH} ];then
TOOL_FILE_NAME=mongodb-database-tools-suse${SYS_NAME}-arm64-${TOOL_VERSION}
fi
TOOL_FILE_NAME_TGZ=${TOOL_FILE_NAME}.tgz
if [ ! -f $MG_DIR/${TOOL_FILE_NAME_TGZ} ]; then
wget --no-check-certificate -O $MG_DIR/${TOOL_FILE_NAME_TGZ} https://fastdl.mongodb.org/tools/db/${TOOL_FILE_NAME_TGZ}
fi
if [ ! -d $MG_DIR/${TOOL_FILE_NAME_TGZ} ];then
cd $MG_DIR && tar -zxvf ${TOOL_FILE_NAME_TGZ}
fi
cd ${MG_DIR}/${TOOL_FILE_NAME} && cp -rf ./bin $serverPath/mongodb
cd ${MG_DIR} && rm -rf ${MG_DIR}/${TOOL_FILE_NAME}

View File

@@ -0,0 +1,99 @@
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin
export PATH
curPath=`pwd`
rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
VERSION=9.0.4
SYS_ARCH=`arch`
SYS_VERSION_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}'`
SYS_NAME=${SYS_VERSION_ID/./}
# https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-ubuntu2004-4.4.23.tgz
if [ "$SYS_NAME" -gt "2404" ];then
SYS_NAME="2404"
fi
if [ "$SYS_NAME" -lt "2004" ];then
SYS_NAME="2004"
fi
if [ "$SYS_NAME" = "2204" ];then
SYS_NAME="2204"
fi
if [ "$SYS_NAME" = "2404" ];then
SYS_NAME="2404"
fi
MG_DIR=$serverPath/source/mongodb
mkdir -p $MG_DIR
FILE_NAME=mongodb-linux-${SYS_ARCH}-ubuntu${SYS_NAME}-${VERSION}
FILE_NAME_TGZ=${FILE_NAME}.tgz
if [ ! -f $MG_DIR/${FILE_NAME_TGZ} ]; then
wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/linux/${FILE_NAME_TGZ}
echo "wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/linux/${FILE_NAME_TGZ}"
fi
if [ ! -d $MG_DIR/${FILE_NAME} ];then
cd $MG_DIR && tar -zxvf ${FILE_NAME_TGZ}
fi
if [ ! -f $serverPath/mongodb/bin/mongod ];then
mkdir -p $serverPath/mongodb
cd $MG_DIR/${FILE_NAME} && cp -rf ./bin $serverPath/mongodb
fi
cd ${MG_DIR} && rm -rf ${MG_DIR}/${FILE_NAME}
#--------------- mongosh tool install ------------------ #
TOOL_VERSION=2.2.5
TOOL_FILE_NAME=mongosh-${TOOL_VERSION}-linux-x64
if [ "aarch64" = ${SYS_ARCH} ];then
TOOL_FILE_NAME=mongosh-${TOOL_VERSION}-linux-arm64
fi
TOOL_FILE_NAME_TGZ=${TOOL_FILE_NAME}.tgz
if [ ! -f $MG_DIR/${TOOL_FILE_NAME_TGZ} ]; then
wget --no-check-certificate -O $MG_DIR/${TOOL_FILE_NAME_TGZ} https://downloads.mongodb.com/compass/${TOOL_FILE_NAME_TGZ}
echo "wget --no-check-certificate -O $MG_DIR/${TOOL_FILE_NAME_TGZ} https://downloads.mongodb.com/compass/${TOOL_FILE_NAME_TGZ}"
fi
if [ ! -d $MG_DIR/${TOOL_FILE_NAME_TGZ} ];then
cd $MG_DIR && tar -zxvf ${TOOL_FILE_NAME_TGZ}
fi
cd ${MG_DIR}/${TOOL_FILE_NAME} && cp -rf ./bin $serverPath/mongodb
cd ${MG_DIR} && rm -rf ${MG_DIR}/${TOOL_FILE_NAME}
# https://fastdl.mongodb.org/tools/db/mongodb-database-tools-ubuntu2204-x86_64-100.9.4.tgz
#--------------- mongodb database install ------------------ #
TOOL_VERSION=100.9.4
SYS_NAME=2204
TOOL_FILE_NAME=mongodb-database-tools-ubuntu${SYS_NAME}-x86_64-${TOOL_VERSION}
if [ "aarch64" = ${SYS_ARCH} ];then
TOOL_FILE_NAME=mongodb-database-tools-ubuntu${SYS_NAME}-arm64-${TOOL_VERSION}
fi
if [ "arm64" = ${SYS_ARCH} ];then
TOOL_FILE_NAME=mongodb-database-tools-ubuntu${SYS_NAME}-arm64-${TOOL_VERSION}
fi
TOOL_FILE_NAME_TGZ=${TOOL_FILE_NAME}.tgz
if [ ! -f $MG_DIR/${TOOL_FILE_NAME_TGZ} ]; then
wget --no-check-certificate -O $MG_DIR/${TOOL_FILE_NAME_TGZ} https://fastdl.mongodb.org/tools/db/${TOOL_FILE_NAME_TGZ}
fi
if [ ! -d $MG_DIR/${TOOL_FILE_NAME_TGZ} ];then
cd $MG_DIR && tar -zxvf ${TOOL_FILE_NAME_TGZ}
fi
cd ${MG_DIR}/${TOOL_FILE_NAME} && cp -rf ./bin $serverPath/mongodb
cd ${MG_DIR} && rm -rf ${MG_DIR}/${TOOL_FILE_NAME}

View File

@@ -18,7 +18,7 @@ bash ${rootPath}/scripts/getos.sh
echo "bash ${rootPath}/scripts/getos.sh"
OSNAME=`cat ${rootPath}/data/osname.pl`
VERSION_MIN=2.1.7
VERSION_MIN=2.2.8
VERSION=v${VERSION_MIN}
sysName=$(uname | tr '[:upper:]' '[:lower:]')

View File

@@ -0,0 +1,111 @@
[client]
user = root
#password = your_password
port = 33206
socket = {$SERVER_APP_PATH}/mysql.sock
default-character-set = UTF8MB4
[mysqld]
!include {$SERVER_APP_PATH}/etc/mode/classic.cnf
authentication_policy=caching_sha2_password
pid-file = {$SERVER_APP_PATH}/data/mysql.pid
user = mysql
port = 33206
mysqlx_port = 33260
socket = {$SERVER_APP_PATH}/mysql.sock
datadir = {$SERVER_APP_PATH}/data
log-error = {$SERVER_APP_PATH}/data/error.log
server-id = {$SERVER_ID}
default_storage_engine = InnoDB
key_buffer_size = 8M
table_open_cache = 32
sort_buffer_size = 256K
net_buffer_length = 4K
read_buffer_size = 128K
read_rnd_buffer_size = 256K
myisam_sort_buffer_size = 4M
thread_cache_size = 4
lower_case_table_names=1
tmp_table_size = 8M
character-set-server = UTF8MB4
max_connections = 500
max_connect_errors = 100
open_files_limit = 2560
max_allowed_packet = 128M
#skip-external-locking
#skip-grant-tables
#loose-skip-innodb
#skip-networking
#skip-name-resolve
#skip-log-bin
#disable-log-bin
#skip-slave-start
log-bin=mysql-bin
slow_query_log=1
slow-query-log-file={$SERVER_APP_PATH}/data/mysql-slow.log
long_query_time=3
#log_queries_not_using_indexes=on
relay-log=mdserver
relay-log-index=mdserver
#master
#sync_binlog=1
#binlog-do-db
binlog-ignore-db = test
binlog-ignore-db = mysql
binlog-ignore-db = information_schema
binlog-ignore-db = performance_schema
#slave
log_replica_updates
#replicate-do-db
replica_skip_errors=1062,1396
replicate-ignore-db = information_schema
replicate-ignore-db = performance_schema
replicate-ignore-db = mysql
replicate-ignore-db = test
replicate-wild-ignore-table = mysql.%
replicate-wild-ignore-table = information_schema.%
replicate-wild-ignore-table = performance_schema.%
replicate-wild-ignore-table = sys.%
default_storage_engine = InnoDB
innodb_data_home_dir = {$SERVER_APP_PATH}/data
innodb_data_file_path = ibdata1:10M:autoextend
innodb_log_group_home_dir = {$SERVER_APP_PATH}/data
innodb_buffer_pool_size = 16M
innodb_redo_log_capacity = 4G
innodb_log_buffer_size = 8M
innodb_flush_log_at_trx_commit = 1
innodb_lock_wait_timeout = 120
innodb_max_dirty_pages_pct = 90
innodb_read_io_threads = 1
innodb_write_io_threads = 1
innodb_file_per_table = 1
binlog_expire_logs_seconds=604800
secure-file-priv={$SERVER_APP_PATH}/tmp
[mysqldump]
quick
[mysql]
no-auto-rehash
[myisamchk]
key_buffer_size = 20M
sort_buffer_size = 20M
read_buffer = 2M
write_buffer = 2M
[mysqlhotcopy]
interactive-timeout

View File

@@ -0,0 +1,111 @@
[client]
user = root
#password = your_password
port = 33206
socket = {$SERVER_APP_PATH}/mysql.sock
default-character-set = UTF8MB4
[mysqld]
!include {$SERVER_APP_PATH}/etc/mode/classic.cnf
authentication_policy=caching_sha2_password
pid-file = {$SERVER_APP_PATH}/data/mysql.pid
user = mysql
port = 33206
mysqlx_port = 33260
socket = {$SERVER_APP_PATH}/mysql.sock
datadir = {$SERVER_APP_PATH}/data
log-error = {$SERVER_APP_PATH}/data/error.log
server-id = {$SERVER_ID}
default_storage_engine = InnoDB
key_buffer_size = 8M
table_open_cache = 32
sort_buffer_size = 256K
net_buffer_length = 4K
read_buffer_size = 128K
read_rnd_buffer_size = 256K
myisam_sort_buffer_size = 4M
thread_cache_size = 4
lower_case_table_names=1
tmp_table_size = 8M
character-set-server = UTF8MB4
max_connections = 500
max_connect_errors = 100
open_files_limit = 2560
max_allowed_packet = 128M
#skip-external-locking
#skip-grant-tables
#loose-skip-innodb
#skip-networking
#skip-name-resolve
#skip-log-bin
#disable-log-bin
#skip-slave-start
log-bin=mysql-bin
slow_query_log=1
slow-query-log-file={$SERVER_APP_PATH}/data/mysql-slow.log
long_query_time=3
#log_queries_not_using_indexes=on
relay-log=mdserver
relay-log-index=mdserver
#master
#sync_binlog=1
#binlog-do-db
binlog-ignore-db = test
binlog-ignore-db = mysql
binlog-ignore-db = information_schema
binlog-ignore-db = performance_schema
#slave
log_replica_updates
#replicate-do-db
replica_skip_errors=1062,1396
replicate-ignore-db = information_schema
replicate-ignore-db = performance_schema
replicate-ignore-db = mysql
replicate-ignore-db = test
replicate-wild-ignore-table = mysql.%
replicate-wild-ignore-table = information_schema.%
replicate-wild-ignore-table = performance_schema.%
replicate-wild-ignore-table = sys.%
default_storage_engine = InnoDB
innodb_data_home_dir = {$SERVER_APP_PATH}/data
innodb_data_file_path = ibdata1:10M:autoextend
innodb_log_group_home_dir = {$SERVER_APP_PATH}/data
innodb_buffer_pool_size = 16M
innodb_redo_log_capacity = 4G
innodb_log_buffer_size = 8M
innodb_flush_log_at_trx_commit = 1
innodb_lock_wait_timeout = 120
innodb_max_dirty_pages_pct = 90
innodb_read_io_threads = 1
innodb_write_io_threads = 1
innodb_file_per_table = 1
binlog_expire_logs_seconds=604800
secure-file-priv={$SERVER_APP_PATH}/tmp
[mysqldump]
quick
[mysql]
no-auto-rehash
[myisamchk]
key_buffer_size = 20M
sort_buffer_size = 20M
read_buffer = 2M
write_buffer = 2M
[mysqlhotcopy]
interactive-timeout

View File

@@ -15,10 +15,12 @@ socket = {$SERVER_APP_PATH}/mysql.sock
datadir = {$SERVER_APP_PATH}/data
log-error = {$SERVER_APP_PATH}/data/error.log
server-id = {$SERVER_ID}
sql-mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
sql-mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
default_storage_engine = InnoDB
language={$SERVER_APP_PATH}/share/english
lc-messages-dir={$SERVER_APP_PATH}/share
explicit_defaults_for_timestamp = ON
key_buffer_size = 8M
table_open_cache = 32
@@ -75,6 +77,11 @@ replicate-ignore-db = performance_schema
replicate-ignore-db = mysql
replicate-ignore-db = test
replicate-wild-ignore-table = mysql.%
replicate-wild-ignore-table = information_schema.%
replicate-wild-ignore-table = performance_schema.%
replicate-wild-ignore-table = sys.%
master_info_repository = table
relay_log_info_repository = table

View File

@@ -65,6 +65,11 @@ binlog-ignore-db = mysql
binlog-ignore-db = information_schema
binlog-ignore-db = performance_schema
replicate-wild-ignore-table = mysql.%
replicate-wild-ignore-table = information_schema.%
replicate-wild-ignore-table = performance_schema.%
replicate-wild-ignore-table = sys.%
#slave
log_replica_updates
#replicate-do-db

View File

@@ -73,6 +73,11 @@ replicate-ignore-db = performance_schema
replicate-ignore-db = mysql
replicate-ignore-db = test
replicate-wild-ignore-table = mysql.%
replicate-wild-ignore-table = information_schema.%
replicate-wild-ignore-table = performance_schema.%
replicate-wild-ignore-table = sys.%
default_storage_engine = InnoDB
innodb_data_home_dir = {$SERVER_APP_PATH}/data
innodb_data_file_path = ibdata1:10M:autoextend

View File

@@ -73,6 +73,11 @@ replicate-ignore-db = performance_schema
replicate-ignore-db = mysql
replicate-ignore-db = test
replicate-wild-ignore-table = mysql.%
replicate-wild-ignore-table = information_schema.%
replicate-wild-ignore-table = performance_schema.%
replicate-wild-ignore-table = sys.%
default_storage_engine = InnoDB
innodb_data_home_dir = {$SERVER_APP_PATH}/data
innodb_data_file_path = ibdata1:10M:autoextend

View File

@@ -73,6 +73,11 @@ replicate-ignore-db = performance_schema
replicate-ignore-db = mysql
replicate-ignore-db = test
replicate-wild-ignore-table = mysql.%
replicate-wild-ignore-table = information_schema.%
replicate-wild-ignore-table = performance_schema.%
replicate-wild-ignore-table = sys.%
default_storage_engine = InnoDB
innodb_data_home_dir = {$SERVER_APP_PATH}/data
innodb_data_file_path = ibdata1:10M:autoextend

View File

@@ -73,6 +73,11 @@ replicate-ignore-db = performance_schema
replicate-ignore-db = mysql
replicate-ignore-db = test
replicate-wild-ignore-table = mysql.%
replicate-wild-ignore-table = information_schema.%
replicate-wild-ignore-table = performance_schema.%
replicate-wild-ignore-table = sys.%
default_storage_engine = InnoDB
innodb_data_home_dir = {$SERVER_APP_PATH}/data
innodb_data_file_path = ibdata1:10M:autoextend

View File

@@ -73,6 +73,11 @@ replicate-ignore-db = performance_schema
replicate-ignore-db = mysql
replicate-ignore-db = test
replicate-wild-ignore-table = mysql.%
replicate-wild-ignore-table = information_schema.%
replicate-wild-ignore-table = performance_schema.%
replicate-wild-ignore-table = sys.%
default_storage_engine = InnoDB
innodb_data_home_dir = {$SERVER_APP_PATH}/data
innodb_data_file_path = ibdata1:10M:autoextend

View File

@@ -64,6 +64,7 @@ binlog-ignore-db = mysql
binlog-ignore-db = information_schema
binlog-ignore-db = performance_schema
#slave
log_replica_updates
#replicate-do-db
@@ -73,6 +74,11 @@ replicate-ignore-db = performance_schema
replicate-ignore-db = mysql
replicate-ignore-db = test
replicate-wild-ignore-table = mysql.%
replicate-wild-ignore-table = information_schema.%
replicate-wild-ignore-table = performance_schema.%
replicate-wild-ignore-table = sys.%
default_storage_engine = InnoDB
innodb_data_home_dir = {$SERVER_APP_PATH}/data
innodb_data_file_path = ibdata1:10M:autoextend

View File

@@ -73,6 +73,11 @@ replicate-ignore-db = performance_schema
replicate-ignore-db = mysql
replicate-ignore-db = test
replicate-wild-ignore-table = mysql.%
replicate-wild-ignore-table = information_schema.%
replicate-wild-ignore-table = performance_schema.%
replicate-wild-ignore-table = sys.%
default_storage_engine = InnoDB
innodb_data_home_dir = {$SERVER_APP_PATH}/data
innodb_data_file_path = ibdata1:10M:autoextend

View File

@@ -0,0 +1,111 @@
[client]
user = root
#password = your_password
port = 33206
socket = {$SERVER_APP_PATH}/mysql.sock
default-character-set = UTF8MB4
[mysqld]
!include {$SERVER_APP_PATH}/etc/mode/classic.cnf
authentication_policy=caching_sha2_password
pid-file = {$SERVER_APP_PATH}/data/mysql.pid
user = mysql
port = 33206
mysqlx_port = 33260
socket = {$SERVER_APP_PATH}/mysql.sock
datadir = {$SERVER_APP_PATH}/data
log-error = {$SERVER_APP_PATH}/data/error.log
server-id = {$SERVER_ID}
default_storage_engine = InnoDB
key_buffer_size = 8M
table_open_cache = 32
sort_buffer_size = 256K
net_buffer_length = 4K
read_buffer_size = 128K
read_rnd_buffer_size = 256K
myisam_sort_buffer_size = 4M
thread_cache_size = 4
lower_case_table_names=1
tmp_table_size = 8M
character-set-server = UTF8MB4
max_connections = 500
max_connect_errors = 100
open_files_limit = 2560
max_allowed_packet = 128M
#skip-external-locking
#skip-grant-tables
#loose-skip-innodb
#skip-networking
#skip-name-resolve
#skip-log-bin
#disable-log-bin
#skip-slave-start
log-bin=mysql-bin
slow_query_log=1
slow-query-log-file={$SERVER_APP_PATH}/data/mysql-slow.log
long_query_time=3
#log_queries_not_using_indexes=on
relay-log=mdserver
relay-log-index=mdserver
#master
#sync_binlog=1
#binlog-do-db
binlog-ignore-db = test
binlog-ignore-db = mysql
binlog-ignore-db = information_schema
binlog-ignore-db = performance_schema
#slave
log_replica_updates
#replicate-do-db
replica_skip_errors=1062,1396
replicate-ignore-db = information_schema
replicate-ignore-db = performance_schema
replicate-ignore-db = mysql
replicate-ignore-db = test
replicate-wild-ignore-table = mysql.%
replicate-wild-ignore-table = information_schema.%
replicate-wild-ignore-table = performance_schema.%
replicate-wild-ignore-table = sys.%
default_storage_engine = InnoDB
innodb_data_home_dir = {$SERVER_APP_PATH}/data
innodb_data_file_path = ibdata1:10M:autoextend
innodb_log_group_home_dir = {$SERVER_APP_PATH}/data
innodb_buffer_pool_size = 16M
innodb_redo_log_capacity = 4G
innodb_log_buffer_size = 8M
innodb_flush_log_at_trx_commit = 1
innodb_lock_wait_timeout = 120
innodb_max_dirty_pages_pct = 90
innodb_read_io_threads = 1
innodb_write_io_threads = 1
innodb_file_per_table = 1
binlog_expire_logs_seconds=604800
secure-file-priv={$SERVER_APP_PATH}/tmp
[mysqldump]
quick
[mysql]
no-auto-rehash
[myisamchk]
key_buffer_size = 20M
sort_buffer_size = 20M
read_buffer = 2M
write_buffer = 2M
[mysqlhotcopy]
interactive-timeout

File diff suppressed because it is too large Load Diff

View File

@@ -7,7 +7,7 @@
"type":"运行环境",
"ps":"一种关系数据库管理系统(极速安装)",
"todo_versions":["5.7","8.0"],
"versions":["5.7","8.0","8.2","8.3","8.4","9.0","9.1","9.2","9.3"],
"versions":["5.7","8.0","8.2","8.3","8.4","9.0","9.1","9.2","9.3","9.7","26.7","26.10"],
"shell":"install.sh",
"install_pre_inspection":true,
"uninstall_pre_inspection":true,

View File

@@ -0,0 +1,377 @@
#!/bin/sh
# Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB
# This file is public domain and comes with NO WARRANTY of any kind
# MySQL daemon start/stop script.
# Usually this is put in /etc/init.d (at least on machines SYSV R4 based
# systems) and linked to /etc/rc3.d/S99mysql and /etc/rc0.d/K01mysql.
# When this is done the mysql server will be started when the machine is
# started and shut down when the systems goes down.
# Comments to support chkconfig on RedHat Linux
# chkconfig: 2345 64 36
# description: A very fast and reliable SQL database engine.
# Comments to support LSB init script conventions
### BEGIN INIT INFO
# Provides: mysql
# Required-Start: $local_fs $network $remote_fs
# Should-Start: ypbind nscd ldap ntpd xntpd
# Required-Stop: $local_fs $network $remote_fs
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: start and stop MySQL
# Description: MySQL is a very fast and reliable SQL database engine.
### END INIT INFO
# If you install MySQL on some other places than /Users/midoks/Desktop/fwww/server/mysql, then you
# have to do one of the following things for this script to work:
#
# - Run this script from within the MySQL installation directory
# - Create a /etc/my.cnf file with the following information:
# [mysqld]
# basedir=<path-to-mysql-installation-directory>
# - Add the above to any other configuration file (for example ~/.my.ini)
# and copy my_print_defaults to /usr/bin
# - Add the path to the mysql-installation-directory to the basedir variable
# below.
#
# If you want to affect other MySQL variables, you should make your changes
# in the /etc/my.cnf, ~/.my.cnf or other MySQL configuration files.
# If you change base dir, you must also change datadir. These may get
# overwritten by settings in the MySQL configuration files.
basedir=
datadir=
# Default value, in seconds, afterwhich the script should timeout waiting
# for server start.
# Value here is overriden by value in my.cnf.
# 0 means don't wait at all
# Negative numbers mean to wait indefinitely
service_startup_timeout=900
# Lock directory for RedHat / SuSE.
lockdir='/var/lock/subsys'
lock_file_path="$lockdir/mysql"
# The following variables are only set for letting mysql.server find things.
# Set some defaults
mysqld_pid_file_path=
if test -z "$basedir"
then
basedir={$SERVER_APP_PATH}
bindir={$SERVER_APP_PATH}/bin
if test -z "$datadir"
then
datadir={$SERVER_APP_PATH}/data
fi
sbindir={$SERVER_APP_PATH}/bin
libexecdir={$SERVER_APP_PATH}/bin
else
bindir="$basedir/bin"
if test -z "$datadir"
then
datadir="$basedir/data"
fi
sbindir="$basedir/sbin"
libexecdir="$basedir/libexec"
fi
# datadir_set is used to determine if datadir was set (and so should be
# *not* set inside of the --basedir= handler.)
datadir_set=
#
# Use LSB init script functions for printing messages, if possible
#
lsb_functions="/lib/lsb/init-functions"
if test -f $lsb_functions ; then
. $lsb_functions
else
log_success_msg()
{
echo " SUCCESS! $@"
}
log_failure_msg()
{
echo " ERROR! $@"
}
fi
PATH="/sbin:/usr/sbin:/bin:/usr/bin:$basedir/bin"
export PATH
mode=$1 # start or stop
[ $# -ge 1 ] && shift
other_args="$*" # uncommon, but needed when called from an RPM upgrade action
# Expected: "--skip-networking --skip-grant-tables"
# They are not checked here, intentionally, as it is the resposibility
# of the "spec" file author to give correct arguments only.
case `echo "testing\c"`,`echo -n testing` in
*c*,-n*) echo_n= echo_c= ;;
*c*,*) echo_n=-n echo_c= ;;
*) echo_n= echo_c='\c' ;;
esac
parse_server_arguments() {
for arg do
case "$arg" in
--basedir=*) basedir=`echo "$arg" | sed -e 's/^[^=]*=//'`
bindir="$basedir/bin"
if test -z "$datadir_set"; then
datadir="$basedir/data"
fi
sbindir="$basedir/sbin"
libexecdir="$basedir/libexec"
;;
--datadir=*) datadir=`echo "$arg" | sed -e 's/^[^=]*=//'`
datadir_set=1
;;
--pid-file=*) mysqld_pid_file_path=`echo "$arg" | sed -e 's/^[^=]*=//'` ;;
--service-startup-timeout=*) service_startup_timeout=`echo "$arg" | sed -e 's/^[^=]*=//'` ;;
esac
done
}
wait_for_pid () {
verb="$1" # created | removed
pid="$2" # process ID of the program operating on the pid-file
pid_file_path="$3" # path to the PID file.
i=0
avoid_race_condition="by checking again"
while test $i -ne $service_startup_timeout ; do
case "$verb" in
'created')
# wait for a PID-file to pop into existence.
test -s "$pid_file_path" && i='' && break
;;
'removed')
# wait for this PID-file to disappear
test ! -s "$pid_file_path" && i='' && break
;;
*)
echo "wait_for_pid () usage: wait_for_pid created|removed pid pid_file_path"
exit 1
;;
esac
# if server isn't running, then pid-file will never be updated
if test -n "$pid"; then
if kill -0 "$pid" 2>/dev/null; then
: # the server still runs
else
# The server may have exited between the last pid-file check and now.
if test -n "$avoid_race_condition"; then
avoid_race_condition=""
continue # Check again.
fi
# there's nothing that will affect the file.
log_failure_msg "The server quit without updating PID file ($pid_file_path)."
return 1 # not waiting any more.
fi
fi
echo $echo_n ".$echo_c"
i=`expr $i + 1`
sleep 1
done
if test -z "$i" ; then
log_success_msg
return 0
else
log_failure_msg
return 1
fi
}
# Get arguments from the my.cnf file,
# the only group, which is read from now on is [mysqld]
if test -x "$bindir/my_print_defaults"; then
print_defaults="$bindir/my_print_defaults"
else
# Try to find basedir in /etc/my.cnf
conf=/etc/my.cnf
print_defaults=
if test -r $conf
then
subpat='^[^=]*basedir[^=]*=\(.*\)$'
dirs=`sed -e "/$subpat/!d" -e 's//\1/' $conf`
for d in $dirs
do
d=`echo $d | sed -e 's/[ ]//g'`
if test -x "$d/bin/my_print_defaults"
then
print_defaults="$d/bin/my_print_defaults"
break
fi
done
fi
# Hope it's in the PATH ... but I doubt it
test -z "$print_defaults" && print_defaults="my_print_defaults"
fi
#
# Read defaults file from 'basedir'. If there is no defaults file there
# check if it's in the old (depricated) place (datadir) and read it from there
#
extra_args=""
if test -r "$basedir/my.cnf"
then
extra_args="-e $basedir/my.cnf"
fi
parse_server_arguments `$print_defaults $extra_args mysqld server mysql_server mysql.server`
#
# Set pid file if not given
#
found_pid=`cd $datadir && ls |grep '.pid'`
if test -z "$mysqld_pid_file_path"
then
mysqld_pid_file_path=$datadir/$found_pid
else
case "$mysqld_pid_file_path" in
/* ) ;;
* ) mysqld_pid_file_path="$datadir/$mysqld_pid_file_path" ;;
esac
fi
case "$mode" in
'start')
# Start daemon
# Safeguard (relative paths, core dumps..)
cd $basedir
echo $echo_n "Starting MySQL"
if test -x $bindir/mysqld_safe
then
# Give extra arguments to mysqld with the my.cnf file. This script
# may be overwritten at next upgrade.
$bindir/mysqld_safe --defaults-file=$basedir/etc/my.cnf --datadir="$datadir" $other_args >/dev/null &
wait_for_pid created "$!" "$mysqld_pid_file_path"; return_value=$?
# Make lock for RedHat / SuSE
if test -w "$lockdir"
then
touch "$lock_file_path"
fi
exit $return_value
else
log_failure_msg "Couldn't find MySQL server ($bindir/mysqld_safe)"
fi
;;
'stop')
# Stop daemon. We use a signal here to avoid having to know the
# root password.
if test -s "$mysqld_pid_file_path"
then
# signal mysqld_safe that it needs to stop
touch "$mysqld_pid_file_path.shutdown"
mysqld_pid=`cat "$mysqld_pid_file_path"`
if (kill -0 $mysqld_pid 2>/dev/null)
then
echo $echo_n "Shutting down MySQL"
kill $mysqld_pid
# mysqld should remove the pid file when it exits, so wait for it.
wait_for_pid removed "$mysqld_pid" "$mysqld_pid_file_path"; return_value=$?
else
log_failure_msg "MySQL server process #$mysqld_pid is not running!"
rm "$mysqld_pid_file_path"
fi
# Delete lock for RedHat / SuSE
if test -f "$lock_file_path"
then
rm -f "$lock_file_path"
fi
exit $return_value
else
log_failure_msg "MySQL server PID file could not be found!"
fi
;;
'restart')
# Stop the service and regardless of whether it was
# running or not, start it again.
if $0 stop $other_args; then
$0 start $other_args
else
log_failure_msg "Failed to stop running server, so refusing to try to start."
exit 1
fi
;;
'reload'|'force-reload')
if test -s "$mysqld_pid_file_path" ; then
read mysqld_pid < "$mysqld_pid_file_path"
kill -HUP $mysqld_pid && log_success_msg "Reloading service MySQL"
touch "$mysqld_pid_file_path"
else
log_failure_msg "MySQL PID file could not be found!"
exit 1
fi
;;
'status')
# First, check to see if pid file exists
if test -s "$mysqld_pid_file_path" ; then
read mysqld_pid < "$mysqld_pid_file_path"
if kill -0 $mysqld_pid 2>/dev/null ; then
log_success_msg "MySQL running ($mysqld_pid)"
exit 0
else
log_failure_msg "MySQL is not running, but PID file exists"
exit 1
fi
else
# Try to find appropriate mysqld process
mysqld_pid=`pgrep -d' ' -f $libexecdir/mysqld`
# test if multiple pids exist
pid_count=`echo $mysqld_pid | wc -w`
if test $pid_count -gt 1 ; then
log_failure_msg "Multiple MySQL running but PID file could not be found ($mysqld_pid)"
exit 5
elif test -z $mysqld_pid ; then
if test -f "$lock_file_path" ; then
log_failure_msg "MySQL is not running, but lock file ($lock_file_path) exists"
exit 2
fi
log_failure_msg "MySQL is not running"
exit 3
else
log_failure_msg "MySQL is running but PID file could not be found"
exit 4
fi
fi
;;
*)
# usage
basename=`basename "$0"`
echo "Usage: $basename {start|stop|restart|reload|force-reload|status} [ MySQL server options ]"
exit 1
;;
esac
exit 0

View File

@@ -0,0 +1,49 @@
# Copyright (c) 2015, 2022, Oracle and/or its affiliates.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License, version 2.0,
# as published by the Free Software Foundation.
#
# This program is also distributed with certain software (including
# but not limited to OpenSSL) that is licensed under separate terms,
# as designated in a particular file or component or in included license
# documentation. The authors of MySQL hereby grant you an additional
# permission to link the program and your derivative works with the
# separately licensed software that they have included with MySQL.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License, version 2.0, for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
# MySQL systemd service file
[Unit]
Description=MySQL Community Server
Documentation=man:mysqld(8)
Documentation=http://dev.mysql.com/doc/refman/en/using-systemd.html
After=network.target
[Install]
WantedBy=multi-user.target
[Service]
User=mysql
Group=mysql
Type=notify
ExecStart={$SERVER_PATH}/mysql-community/bin/mysqld --defaults-file={$SERVER_PATH}/mysql-community/etc/my.cnf
TimeoutSec=600
LimitNOFILE = 10000
Restart=on-failure
RestartPreventExitStatus=1
# Always restart when mysqld exits with exit code of 16. This special exit code
# is used by mysqld for RESTART SQL.
RestartForceExitStatus=16
# Set enviroment variable MYSQLD_PARENT_PID. This is required for restart.
Environment=MYSQLD_PARENT_PID=1

View File

@@ -0,0 +1,49 @@
# Copyright (c) 2015, 2022, Oracle and/or its affiliates.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License, version 2.0,
# as published by the Free Software Foundation.
#
# This program is also distributed with certain software (including
# but not limited to OpenSSL) that is licensed under separate terms,
# as designated in a particular file or component or in included license
# documentation. The authors of MySQL hereby grant you an additional
# permission to link the program and your derivative works with the
# separately licensed software that they have included with MySQL.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License, version 2.0, for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
# MySQL systemd service file
[Unit]
Description=MySQL Community Server
Documentation=man:mysqld(8)
Documentation=http://dev.mysql.com/doc/refman/en/using-systemd.html
After=network.target
[Install]
WantedBy=multi-user.target
[Service]
User=mysql
Group=mysql
Type=notify
ExecStart={$SERVER_PATH}/mysql-community/bin/mysqld --defaults-file={$SERVER_PATH}/mysql-community/etc/my.cnf
TimeoutSec=600
LimitNOFILE = 10000
Restart=on-failure
RestartPreventExitStatus=1
# Always restart when mysqld exits with exit code of 16. This special exit code
# is used by mysqld for RESTART SQL.
RestartForceExitStatus=16
# Set enviroment variable MYSQLD_PARENT_PID. This is required for restart.
Environment=MYSQLD_PARENT_PID=1

View File

@@ -0,0 +1,49 @@
# Copyright (c) 2015, 2022, Oracle and/or its affiliates.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License, version 2.0,
# as published by the Free Software Foundation.
#
# This program is also distributed with certain software (including
# but not limited to OpenSSL) that is licensed under separate terms,
# as designated in a particular file or component or in included license
# documentation. The authors of MySQL hereby grant you an additional
# permission to link the program and your derivative works with the
# separately licensed software that they have included with MySQL.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License, version 2.0, for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
# MySQL systemd service file
[Unit]
Description=MySQL Community Server
Documentation=man:mysqld(8)
Documentation=http://dev.mysql.com/doc/refman/en/using-systemd.html
After=network.target
[Install]
WantedBy=multi-user.target
[Service]
User=mysql
Group=mysql
Type=notify
ExecStart={$SERVER_PATH}/mysql-community/bin/mysqld --defaults-file={$SERVER_PATH}/mysql-community/etc/my.cnf
TimeoutSec=600
LimitNOFILE = 10000
Restart=on-failure
RestartPreventExitStatus=1
# Always restart when mysqld exits with exit code of 16. This special exit code
# is used by mysqld for RESTART SQL.
RestartForceExitStatus=16
# Set enviroment variable MYSQLD_PARENT_PID. This is required for restart.
Environment=MYSQLD_PARENT_PID=1

View File

@@ -1,16 +1,18 @@
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin
export PATH
curPath=`pwd`
rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
sysName=`uname`
if [ -f ${rootPath}/bin/activate ];then
. ${rootPath}/bin/activate
fi
# cd /Users/midoks/Desktop/mwdev/server/mdserver-web/plugins/mysql-community && bash install.sh install 9。7
# https://dev.mysql.com/downloads/mysql/
# https://downloads.mysql.com/archives/community/
@@ -22,7 +24,6 @@ fi
# /www/server/mysql-community/bin/mysqld --basedir=/www/server/mysql-community --datadir=/www/server/mysql-community/data --initialize-insecure --explicit_defaults_for_timestamp
# . bin/activate
# cd /www/server/mdserver-web/plugins/mysql-community && bash install.sh install 5.7
# cd /www/server/mdserver-web/plugins/mysql-community && bash install.sh install 9.3
# cd /www/server/mdserver-web/plugins/mysql-community && bash install.sh uninstall 9.0
# cd /www/server/mdserver-web && python3 plugins/mysql-community/index.py start 8.0
@@ -136,8 +137,16 @@ if [ "${action}" = "uninstall" ];then
fi
fi
if [ "$sysName" = "Darwin" ];then
if [ ! -f $curPath/versions/$2/install_mac.sh ];then
echo "not supported for the time being"
else
sh -x $curPath/versions/$2/install_mac.sh $1
fi
else
sh -x $curPath/versions/$2/install_generic.sh $1
fi
sh -x $curPath/versions/$2/install_generic.sh $1
if [ "${action}" = "install" ];then
#初始化

View File

@@ -503,11 +503,11 @@ function setRootPwd(type, pwd){
var index = layer.open({
type: 1,
area: '500px',
area: '800px',
title: '修改数据库密码',
closeBtn: 1,
shift: 5,
btn:["提交", "关闭", "复制ROOT密码", "强制修改"],
btn:["提交", "关闭", "复制ROOT密码", "修改本地ROOT记录", "强改ROOT密码"],
shadeClose: true,
content: "<form class='bt-form pd20' id='mod_pwd'>\
<div class='line'>\
@@ -533,7 +533,7 @@ function setRootPwd(type, pwd){
return false;
},
btn4:function(layerIndex){
layer.confirm('强制修改,是为了在重建时使用,确定强制?', {
layer.confirm('修改本地ROOT记录,确定修改?', {
btn: ['确定', '取消']
}, function(index, layero){
layer.close(index);
@@ -547,6 +547,22 @@ function setRootPwd(type, pwd){
});
});
return false;
},
btn5:function(layerIndex){
layer.confirm('强制修改会重启MySQL,并跳过权限校验真正重置root密码,确定强制?', {
btn: ['确定', '取消']
}, function(index, layero){
layer.close(index);
var password = $("#MyPassword").val();
myPost('set_root_pwd', {password:password,force:'2'}, function(data){
var rdata = $.parseJSON(data.data);
showMsg(rdata.msg,function(){
layer.close(layerIndex);
dbList();
},{icon: rdata.status ? 1 : 2});
});
});
return false;
}
});
}
@@ -614,7 +630,7 @@ function setDbAccess(username){
<span class='tname'>访问权限</span>\
<div class='info-r '>\
<select class='bt-input-text mr5' name='dataAccess' style='width:100px'>\
<option value='127.0.0.1'>本地服务器</option>\
<option value='localhost'>本地服务器</option>\
<option value=\"%\">所有人</option>\
<option value='ip'>指定IP</option>\
</select>\
@@ -622,9 +638,9 @@ function setDbAccess(username){
</div>\
</form>",
success:function(){
if (rdata.msg == '127.0.0.1'){
$('select[name="dataAccess"]').find("option[value='127.0.0.1']").attr("selected",true);
} else if (rdata.msg == '%'){
if (rdata.msg == 'localhost'){
$('select[name="dataAccess"]').find("option[value='localhost']").attr("selected",true);
} else if (rdata.msg.indexOf("%") > -1){
$('select[name="dataAccess"]').find('option[value="%"]').attr("selected",true);
} else if ( rdata.msg == 'ip' ){
$('select[name="dataAccess"]').find('option[value="ip"]').attr("selected",true);
@@ -911,7 +927,7 @@ function delBackup(filename, name, path){
path = "";
}
myPost('delete_db_backup',{filename:filename,path:path},function(){
layer.msg('执行成功!');
layer.msg(rdata.msg, { icon: rdata.status ? 1 : 2 });
setTimeout(function(){
setBackupReq(name);
},2000);
@@ -1117,6 +1133,7 @@ function setBackup(db_name){
content: '<div class="pd15">\
<div class="db_list">\
<button id="btn_backup" class="btn btn-success btn-sm" type="button">备份</button>\
<button id="btn_backup_reload" class="btn btn-success btn-sm" type="button">刷新</button>\
<button id="btn_local_import" class="btn btn-success btn-sm" type="button">外部导入</button>\
</div >\
<div class="divtable">\
@@ -1148,6 +1165,10 @@ function setBackup(db_name){
setLocalImport(db_name);
});
$('#btn_backup_reload').click(function(){
setBackupReq(db_name);
});
setBackupReq(db_name);
},
});
@@ -1801,7 +1822,7 @@ function setDbMasterAccess(username){
<span class='tname'>访问权限</span>\
<div class='info-r '>\
<select class='bt-input-text mr5' name='dataAccess' style='width:100px'>\
<option value='127.0.0.1'>本地服务器</option>\
<option value='localhost'>本地服务器</option>\
<option value=\"%\">所有人</option>\
<option value='ip'>指定IP</option>\
</select>\
@@ -1809,9 +1830,9 @@ function setDbMasterAccess(username){
</div>\
</form>",
success:function(){
if (rdata.msg == '127.0.0.1'){
$('select[name="dataAccess"]').find("option[value='127.0.0.1']").attr("selected",true);
} else if (rdata.msg == '%'){
if (rdata.msg == 'localhost'){
$('select[name="dataAccess"]').find("option[value='localhost']").attr("selected",true);
} else if (rdata.msg.indexOf("%") > -1 ){
$('select[name="dataAccess"]').find('option[value="%"]').attr("selected",true);
} else if ( rdata.msg == 'ip' ){
$('select[name="dataAccess"]').find('option[value="ip"]').attr("selected",true);

View File

@@ -25,7 +25,51 @@ python3 /www/server/mdserver-web/plugins/mysql-community/scripts/backup.py data
'''
class backupTools:
def backupDatabase(self, name, count):
def getDbBackupList(self,dbname=''):
bkDir = mw.getFatherDir() + '/backup/database/mysql-community'
if not os.path.isdir(bkDir):
return []
blist = os.listdir(bkDir)
r = []
bname = 'db_' + dbname
blen = len(bname)
for x in blist:
fbstr = x[0:blen]
if fbstr == bname:
r.append(x)
# 文件名按时间戳命名,排序后即为时间顺序(旧->新)
r.sort()
return r
def getConf(self, mtype='mysql'):
path = mw.getServerDir() + '/' + mtype + '/etc/my.cnf'
return path
def recognizeDbMode(self, mtype='mysql'):
conf = self.getConf(mtype)
# print(conf)
con = mw.readFile(conf)
rep = r"!include %s/(.*)?\.cnf" % (mw.getServerDir() +'/'+ mtype +"/etc/mode",)
mode = 'none'
try:
data = re.findall(rep, con, re.M)
mode = data[0]
except Exception as e:
pass
return mode
def backupDatabase(self, params, count):
params_args = params.split("@")
name = params_args[0]
table_name = ''
if len(params_args) > 1:
table_name = params_args[1]
backup_name = name
if table_name != '':
backup_name = name+'@'+table_name
db_path = mw.getServerDir() + '/mysql-community'
db_name = 'mysql'
find_name = mw.M('databases').dbPos(db_path, 'mysql').where(
@@ -35,19 +79,17 @@ class backupTools:
endDate = time.strftime('%Y/%m/%d %X', time.localtime())
log = "数据库[" + name + "]不存在!"
print("★[" + endDate + "] " + log)
print(
"----------------------------------------------------------------------------")
print("----------------------------------------------------------------------------")
return
backup_path = mw.getFatherDir() + '/backup/database/mysql-community'
if not os.path.exists(backup_path):
mw.execShell("mkdir -p " + backup_path)
filename = backup_path + "/db_" + name + "_" + \
filename = backup_path + "/db_" + backup_name + "_" + \
time.strftime('%Y%m%d_%H%M%S', time.localtime()) + ".sql.gz"
mysql_root = mw.M('config').dbPos(db_path, db_name).where(
"id=?", (1,)).getField('mysql_root')
mysql_root = mw.M('config').dbPos(db_path, db_name).where("id=?", (1,)).getField('mysql_root')
my_conf_path = db_path + '/etc/my.cnf'
mycnf = mw.readFile(my_conf_path)
@@ -58,46 +100,54 @@ class backupTools:
if len(mycnf) > 100:
mw.writeFile(db_path + '/etc/my.cnf', mycnf)
cmd = db_path + "/bin/usr/bin/mysqldump --defaults-file=" + my_conf_path + " --single-transaction -q --default-character-set=utf8mb4 " + name + " | gzip > " + filename
mw.execShell(cmd)
option = ''
# mode = self.recognizeDbMode('mysql-community')
# print(mode)
# if mode == 'gtid':
option = ' --set-gtid-purged=off '
if not os.path.exists(filename):
endDate = time.strftime('%Y/%m/%d %X', time.localtime())
log = "数据库[" + name + "]备份失败!"
print("★[" + endDate + "] " + log)
print(
"----------------------------------------------------------------------------")
return
cmd = db_path + "/bin/mysqldump --defaults-file=" + my_conf_path + " " + option + " --single-transaction -q --default-character-set=utf8mb4 " + name + " | gzip > " + filename
if table_name != '':
cmd = db_path + "/bin/mysqldump --defaults-file=" + my_conf_path + " " + option + " --single-transaction -q --default-character-set=utf8mb4 " + name + " " + table_name + " | gzip > " + filename
# print(cmd)
os.system(cmd)
# mw.execShell(cmd)
mycnf = mw.readFile(db_path + '/etc/my.cnf')
mycnf = mycnf.replace(subStr, sea)
if len(mycnf) > 100:
mw.writeFile(db_path + '/etc/my.cnf', mycnf)
if not os.path.exists(filename):
endDate = time.strftime('%Y/%m/%d %X', time.localtime())
log = "数据库[" + name + "]备份失败!"
print("★[" + endDate + "] " + log)
print("----------------------------------------------------------------------------")
return
endDate = time.strftime('%Y/%m/%d %X', time.localtime())
outTime = time.time() - startTime
pid = mw.M('databases').dbPos(db_path, db_name).where('name=?', (name,)).getField('id')
mw.M('backup').add('type,name,pid,filename,add_time,size', (1, os.path.basename(filename), pid, filename, endDate, os.path.getsize(filename)))
log = "数据库[" + name + "]备份成功,用时[" + str(round(outTime, 2)) + "]秒"
log = "数据库[" + backup_name + "]备份成功,用时[" + str(round(outTime, 2)) + "]秒"
mw.writeLog('计划任务', log)
print("★[" + endDate + "] " + log)
print("|---保留最新的[" + count + "]份备份")
print("|---文件名:" + filename)
backups = self.getDbBackupList(backup_name)
# 清理多余备份
backups = mw.M('backup').where('type=? and pid=?', ('1', pid)).field('id,filename').select()
num = len(backups) - int(count)
if num > 0:
for backup in backups:
mw.execShell("rm -f " + backup['filename'])
mw.M('backup').where('id=?', (backup['id'],)).delete()
mw.execShell("rm -f " + backup_path + "/"+backup)
num -= 1
print("|---已清理过期备份文件:" + backup['filename'])
print("|---已清理过期文件:" + backup)
if num < 1:
break
def backupDatabaseAll(self, save):
db_path = mw.getServerDir() + '/mysql-community'
db_name = 'mysql'

View File

@@ -0,0 +1,83 @@
# -*- coding: utf-8 -*-
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
export DEBIAN_FRONTEND=noninteractive
# https://downloads.mysql.com/archives/community/
curPath=`pwd`
rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
sysName=`uname`
myDir=${serverPath}/source/mysql-community
OS_ARCH=`arch`
MYSQL_VER=26.10.0
SUFFIX_NAME=${MYSQL_VER}-linux-glibc2.28-${OS_ARCH}
# cd /www/server/mdserver-web/plugins/mysql-community && bash install.sh install 9.3
# cd /www/server/mdserver-web && python3 /www/server/mdserver-web/plugins/mysql-community/index.py start 9.3
COMMUNITY_INSTALL()
{
########
mkdir -p $myDir
mkdir -p $serverPath/mysql-community
# Linux - Generic
# https://cdn.mysql.com/archives/mysql-9.3/mysql-9.3.0-linux-glibc2.28-x86_64.tar.xz
# https://cdn.mysql.com/Downloads/MySQL-9.3/mysql-${SUFFIX_NAME}.tar.xz
if [ ! -f ${myDir}/mysql-${SUFFIX_NAME}.tar.xz ];then
wget --no-check-certificate -O ${myDir}/mysql-${SUFFIX_NAME}.tar.xz https://cdn.mysql.com//Downloads/MySQL-26.10/mysql-${SUFFIX_NAME}.tar.xz
fi
if [ -d ${myDir} ];then
cd ${myDir} && tar -Jxf ${myDir}/mysql-${SUFFIX_NAME}.tar.xz
cp -rf ${myDir}/mysql-${SUFFIX_NAME}/* $serverPath/mysql-community
fi
# 测试时可关闭
rm -rf $myDir/mysql-${SUFFIX_NAME}
#######
}
COMMUNITY_UNINSTALL()
{
###
rm -rf $myDir/mysql-${SUFFIX_NAME}
# apt remove -y mysql-server
###
}
Install_mysql()
{
echo '正在安装脚本文件...'
COMMUNITY_INSTALL
if [ "$?" = "0" ];then
mkdir -p $serverPath/mysql-community
echo '26.10' > $serverPath/mysql-community/version.pl
echo '安装完成'
else
echo '26.10' > $serverPath/mysql-community/version.pl
echo "暂时不支持该系统"
fi
}
Uninstall_mysql()
{
COMMUNITY_UNINSTALL
rm -rf $serverPath/mysql-community
echo '卸载完成'
}
action=$1
if [ "${1}" = 'install' ];then
Install_mysql
else
Uninstall_mysql
fi

View File

@@ -0,0 +1,80 @@
# -*- coding: utf-8 -*-
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin
export PATH
export DEBIAN_FRONTEND=noninteractive
# https://downloads.mysql.com/archives/community/
curPath=`pwd`
rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
sysName=`uname`
myDir=${serverPath}/source/mysql-community
OS_ARCH=`arch`
MYSQL_VER=26.10.0
SUFFIX_NAME=${MYSQL_VER}-macos15-arm64
COMMUNITY_INSTALL()
{
########
mkdir -p $myDir
mkdir -p $serverPath/mysql-community
# https://cdn.mysql.com/archives/mysql-26.10/mysql-26.10.0-macos15-arm64.tar.gz
# https://cdn.mysql.com//Downloads/MySQL-26.10/mysql-26.10.0-macos15-arm64.tar.gz
if [ ! -f ${myDir}/mysql-${SUFFIX_NAME}.tar.gz ];then
# wget --no-check-certificate -O ${myDir}/mysql-${SUFFIX_NAME}.tar.gz https://cdn.mysql.com/archives/mysql-8.2/mysql-${SUFFIX_NAME}.tar.gz
wget --no-check-certificate -O ${myDir}/mysql-${SUFFIX_NAME}.tar.gz https://cdn.mysql.com//Downloads/MySQL-26.10/mysql-${SUFFIX_NAME}.tar.gz
fi
if [ -d ${myDir} ];then
cd ${myDir} && tar -zxvf ${myDir}/mysql-${SUFFIX_NAME}.tar.gz
cp -rf ${myDir}/mysql-${SUFFIX_NAME}/* $serverPath/mysql-community
fi
# 测试时可关闭
# rm -rf $myDir/mysql-${SUFFIX_NAME}
#######
}
COMMUNITY_UNINSTALL()
{
###
rm -rf $myDir/mysql-${SUFFIX_NAME}
# apt remove -y mysql-server
###
}
Install_mysql()
{
echo '正在安装脚本文件...'
COMMUNITY_INSTALL
if [ "$?" = "0" ];then
mkdir -p $serverPath/mysql-community
echo '26.10' > $serverPath/mysql-community/version.pl
echo '安装完成'
else
echo '26.10' > $serverPath/mysql-community/version.pl
echo "暂时不支持该系统"
fi
}
Uninstall_mysql()
{
COMMUNITY_UNINSTALL
rm -rf $serverPath/mysql-community
echo '卸载完成'
}
action=$1
if [ "${1}" = 'install' ];then
Install_mysql
else
Uninstall_mysql
fi

View File

@@ -0,0 +1,83 @@
# -*- coding: utf-8 -*-
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin:/opt/homebrew/bin
export PATH
export DEBIAN_FRONTEND=noninteractive
# https://downloads.mysql.com/archives/community/
curPath=`pwd`
rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
sysName=`uname`
myDir=${serverPath}/source/mysql-community
OS_ARCH=`arch`
MYSQL_VER=26.7.0
SUFFIX_NAME=${MYSQL_VER}-linux-glibc2.28-${OS_ARCH}
# cd /www/server/mdserver-web/plugins/mysql-community && bash install.sh install 9.3
# cd /www/server/mdserver-web && python3 /www/server/mdserver-web/plugins/mysql-community/index.py start 9.3
COMMUNITY_INSTALL()
{
########
mkdir -p $myDir
mkdir -p $serverPath/mysql-community
# Linux - Generic
# https://cdn.mysql.com/archives/mysql-9.3/mysql-9.3.0-linux-glibc2.28-x86_64.tar.xz
# https://cdn.mysql.com/Downloads/MySQL-9.3/mysql-${SUFFIX_NAME}.tar.xz
if [ ! -f ${myDir}/mysql-${SUFFIX_NAME}.tar.xz ];then
wget --no-check-certificate -O ${myDir}/mysql-${SUFFIX_NAME}.tar.xz https://cdn.mysql.com//Downloads/MySQL-26.7/mysql-${SUFFIX_NAME}.tar.xz
fi
if [ -d ${myDir} ];then
cd ${myDir} && tar -Jxf ${myDir}/mysql-${SUFFIX_NAME}.tar.xz
cp -rf ${myDir}/mysql-${SUFFIX_NAME}/* $serverPath/mysql-community
fi
# 测试时可关闭
rm -rf $myDir/mysql-${SUFFIX_NAME}
#######
}
COMMUNITY_UNINSTALL()
{
###
rm -rf $myDir/mysql-${SUFFIX_NAME}
# apt remove -y mysql-server
###
}
Install_mysql()
{
echo '正在安装脚本文件...'
COMMUNITY_INSTALL
if [ "$?" = "0" ];then
mkdir -p $serverPath/mysql-community
echo '26.7' > $serverPath/mysql-community/version.pl
echo '安装完成'
else
echo '26.7' > $serverPath/mysql-community/version.pl
echo "暂时不支持该系统"
fi
}
Uninstall_mysql()
{
COMMUNITY_UNINSTALL
rm -rf $serverPath/mysql-community
echo '卸载完成'
}
action=$1
if [ "${1}" = 'install' ];then
Install_mysql
else
Uninstall_mysql
fi

View File

@@ -0,0 +1,78 @@
# -*- coding: utf-8 -*-
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin
export PATH
export DEBIAN_FRONTEND=noninteractive
# https://downloads.mysql.com/archives/community/
curPath=`pwd`
rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
sysName=`uname`
myDir=${serverPath}/source/mysql-community
OS_ARCH=`arch`
MYSQL_VER=26.7.0
SUFFIX_NAME=${MYSQL_VER}-macos15-arm64
COMMUNITY_INSTALL()
{
########
mkdir -p $myDir
mkdir -p $serverPath/mysql-community
# https://cdn.mysql.com/archives/mysql-26.7/mysql-26.7.0-macos15-arm64.tar.gz
if [ ! -f ${myDir}/mysql-${SUFFIX_NAME}.tar.gz ];then
wget --no-check-certificate -O ${myDir}/mysql-${SUFFIX_NAME}.tar.gz https://cdn.mysql.com/archives/mysql-8.2/mysql-${SUFFIX_NAME}.tar.gz
fi
if [ -d ${myDir} ];then
cd ${myDir} && tar -zxvf ${myDir}/mysql-${SUFFIX_NAME}.tar.gz
cp -rf ${myDir}/mysql-${SUFFIX_NAME}/* $serverPath/mysql-community
fi
# 测试时可关闭
# rm -rf $myDir/mysql-${SUFFIX_NAME}
#######
}
COMMUNITY_UNINSTALL()
{
###
rm -rf $myDir/mysql-${SUFFIX_NAME}
# apt remove -y mysql-server
###
}
Install_mysql()
{
echo '正在安装脚本文件...'
COMMUNITY_INSTALL
if [ "$?" = "0" ];then
mkdir -p $serverPath/mysql-community
echo '26.7' > $serverPath/mysql-community/version.pl
echo '安装完成'
else
echo '26.7' > $serverPath/mysql-community/version.pl
echo "暂时不支持该系统"
fi
}
Uninstall_mysql()
{
COMMUNITY_UNINSTALL
rm -rf $serverPath/mysql-community
echo '卸载完成'
}
action=$1
if [ "${1}" = 'install' ];then
Install_mysql
else
Uninstall_mysql
fi

View File

@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin
export PATH
export DEBIAN_FRONTEND=noninteractive

View File

@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin
export PATH
export DEBIAN_FRONTEND=noninteractive
@@ -16,7 +16,7 @@ sysName=`uname`
myDir=${serverPath}/source/mysql-community
OS_ARCH=`arch`
MYSQL_VER=8.0.39
MYSQL_VER=8.0.45
SUFFIX_NAME=${MYSQL_VER}-linux-glibc2.28-${OS_ARCH}
# cd /www/server/mdserver-web/plugins/mysql-community && bash install.sh install 8.0

View File

@@ -0,0 +1,78 @@
# -*- coding: utf-8 -*-
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin
export PATH
export DEBIAN_FRONTEND=noninteractive
# https://downloads.mysql.com/archives/community/
curPath=`pwd`
rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
sysName=`uname`
myDir=${serverPath}/source/mysql-community
OS_ARCH=`arch`
MYSQL_VER=8.0.45
SUFFIX_NAME=${MYSQL_VER}-macos15-arm64
COMMUNITY_INSTALL()
{
########
mkdir -p $myDir
mkdir -p $serverPath/mysql-community
# https://cdn.mysql.com/archives/mysql-8.0/mysql-8.0.45-macos15-arm64.tar.gz
if [ ! -f ${myDir}/mysql-${SUFFIX_NAME}.tar.gz ];then
wget --no-check-certificate -O ${myDir}/mysql-${SUFFIX_NAME}.tar.gz https://cdn.mysql.com/archives/mysql-8.0/mysql-${SUFFIX_NAME}.tar.gz
fi
if [ -d ${myDir} ];then
cd ${myDir} && tar -zxvf ${myDir}/mysql-${SUFFIX_NAME}.tar.gz
cp -rf ${myDir}/mysql-${SUFFIX_NAME}/* $serverPath/mysql-community
fi
# 测试时可关闭
# rm -rf $myDir/mysql-${SUFFIX_NAME}
#######
}
COMMUNITY_UNINSTALL()
{
###
rm -rf $myDir/mysql-${SUFFIX_NAME}
# apt remove -y mysql-server
###
}
Install_mysql()
{
echo '正在安装脚本文件...'
COMMUNITY_INSTALL
if [ "$?" = "0" ];then
mkdir -p $serverPath/mysql-community
echo '8.0' > $serverPath/mysql-community/version.pl
echo '安装完成'
else
echo '8.0' > $serverPath/mysql-community/version.pl
echo "暂时不支持该系统"
fi
}
Uninstall_mysql()
{
COMMUNITY_UNINSTALL
rm -rf $serverPath/mysql-community
echo '卸载完成'
}
action=$1
if [ "${1}" = 'install' ];then
Install_mysql
else
Uninstall_mysql
fi

View File

@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin
export PATH
export DEBIAN_FRONTEND=noninteractive

View File

@@ -0,0 +1,78 @@
# -*- coding: utf-8 -*-
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin
export PATH
export DEBIAN_FRONTEND=noninteractive
# https://downloads.mysql.com/archives/community/
curPath=`pwd`
rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
sysName=`uname`
myDir=${serverPath}/source/mysql-community
OS_ARCH=`arch`
MYSQL_VER=8.2.0
SUFFIX_NAME=${MYSQL_VER}-macos13-arm64
COMMUNITY_INSTALL()
{
########
mkdir -p $myDir
mkdir -p $serverPath/mysql-community
# https://cdn.mysql.com/archives/mysql-8.2/mysql-8.2.0-macos13-arm64.tar.gz
if [ ! -f ${myDir}/mysql-${SUFFIX_NAME}.tar.gz ];then
wget --no-check-certificate -O ${myDir}/mysql-${SUFFIX_NAME}.tar.gz https://cdn.mysql.com/archives/mysql-8.2/mysql-${SUFFIX_NAME}.tar.gz
fi
if [ -d ${myDir} ];then
cd ${myDir} && tar -zxvf ${myDir}/mysql-${SUFFIX_NAME}.tar.gz
cp -rf ${myDir}/mysql-${SUFFIX_NAME}/* $serverPath/mysql-community
fi
# 测试时可关闭
# rm -rf $myDir/mysql-${SUFFIX_NAME}
#######
}
COMMUNITY_UNINSTALL()
{
###
rm -rf $myDir/mysql-${SUFFIX_NAME}
# apt remove -y mysql-server
###
}
Install_mysql()
{
echo '正在安装脚本文件...'
COMMUNITY_INSTALL
if [ "$?" = "0" ];then
mkdir -p $serverPath/mysql-community
echo '8.2' > $serverPath/mysql-community/version.pl
echo '安装完成'
else
echo '8.2' > $serverPath/mysql-community/version.pl
echo "暂时不支持该系统"
fi
}
Uninstall_mysql()
{
COMMUNITY_UNINSTALL
rm -rf $serverPath/mysql-community
echo '卸载完成'
}
action=$1
if [ "${1}" = 'install' ];then
Install_mysql
else
Uninstall_mysql
fi

View File

@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin
export PATH
export DEBIAN_FRONTEND=noninteractive

View File

@@ -0,0 +1,78 @@
# -*- coding: utf-8 -*-
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin
export PATH
export DEBIAN_FRONTEND=noninteractive
# https://downloads.mysql.com/archives/community/
curPath=`pwd`
rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
sysName=`uname`
myDir=${serverPath}/source/mysql-community
OS_ARCH=`arch`
MYSQL_VER=8.3.0
SUFFIX_NAME=${MYSQL_VER}-macos14-arm64
COMMUNITY_INSTALL()
{
########
mkdir -p $myDir
mkdir -p $serverPath/mysql-community
# https://cdn.mysql.com/archives/mysql-8.3/mysql-8.3.0-macos14-arm64.tar.gz
if [ ! -f ${myDir}/mysql-${SUFFIX_NAME}.tar.gz ];then
wget --no-check-certificate -O ${myDir}/mysql-${SUFFIX_NAME}.tar.gz https://cdn.mysql.com/archives/mysql-8.3/mysql-${SUFFIX_NAME}.tar.gz
fi
if [ -d ${myDir} ];then
cd ${myDir} && tar -zxvf ${myDir}/mysql-${SUFFIX_NAME}.tar.gz
cp -rf ${myDir}/mysql-${SUFFIX_NAME}/* $serverPath/mysql-community
fi
# 测试时可关闭
# rm -rf $myDir/mysql-${SUFFIX_NAME}
#######
}
COMMUNITY_UNINSTALL()
{
###
rm -rf $myDir/mysql-${SUFFIX_NAME}
# apt remove -y mysql-server
###
}
Install_mysql()
{
echo '正在安装脚本文件...'
COMMUNITY_INSTALL
if [ "$?" = "0" ];then
mkdir -p $serverPath/mysql-community
echo '8.3' > $serverPath/mysql-community/version.pl
echo '安装完成'
else
echo '8.3' > $serverPath/mysql-community/version.pl
echo "暂时不支持该系统"
fi
}
Uninstall_mysql()
{
COMMUNITY_UNINSTALL
rm -rf $serverPath/mysql-community
echo '卸载完成'
}
action=$1
if [ "${1}" = 'install' ];then
Install_mysql
else
Uninstall_mysql
fi

View File

@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin
export PATH
export DEBIAN_FRONTEND=noninteractive
@@ -16,7 +16,7 @@ sysName=`uname`
myDir=${serverPath}/source/mysql-community
OS_ARCH=`arch`
MYSQL_VER=8.4.2
MYSQL_VER=8.4.11
SUFFIX_NAME=${MYSQL_VER}-linux-glibc2.28-${OS_ARCH}
# cd /www/server/mdserver-web/plugins/mysql-community && bash install.sh install 8.4

View File

@@ -0,0 +1,78 @@
# -*- coding: utf-8 -*-
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin
export PATH
export DEBIAN_FRONTEND=noninteractive
# https://downloads.mysql.com/archives/community/
curPath=`pwd`
rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
sysName=`uname`
myDir=${serverPath}/source/mysql-community
OS_ARCH=`arch`
MYSQL_VER=8.4.11
SUFFIX_NAME=${MYSQL_VER}-macos15-arm64
COMMUNITY_INSTALL()
{
########
mkdir -p $myDir
mkdir -p $serverPath/mysql-community
# https://cdn.mysql.com/archives/mysql-8.4/mysql-8.4.11-macos15-arm64.tar.gz
if [ ! -f ${myDir}/mysql-${SUFFIX_NAME}.tar.gz ];then
wget --no-check-certificate -O ${myDir}/mysql-${SUFFIX_NAME}.tar.gz https://cdn.mysql.com/archives/mysql-8.4/mysql-${SUFFIX_NAME}.tar.gz
fi
if [ -d ${myDir} ];then
cd ${myDir} && tar -zxvf ${myDir}/mysql-${SUFFIX_NAME}.tar.gz
cp -rf ${myDir}/mysql-${SUFFIX_NAME}/* $serverPath/mysql-community
fi
# 测试时可关闭
# rm -rf $myDir/mysql-${SUFFIX_NAME}
#######
}
COMMUNITY_UNINSTALL()
{
###
rm -rf $myDir/mysql-${SUFFIX_NAME}
# apt remove -y mysql-server
###
}
Install_mysql()
{
echo '正在安装脚本文件...'
COMMUNITY_INSTALL
if [ "$?" = "0" ];then
mkdir -p $serverPath/mysql-community
echo '8.4' > $serverPath/mysql-community/version.pl
echo '安装完成'
else
echo '8.4' > $serverPath/mysql-community/version.pl
echo "暂时不支持该系统"
fi
}
Uninstall_mysql()
{
COMMUNITY_UNINSTALL
rm -rf $serverPath/mysql-community
echo '卸载完成'
}
action=$1
if [ "${1}" = 'install' ];then
Install_mysql
else
Uninstall_mysql
fi

View File

@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin
export PATH
export DEBIAN_FRONTEND=noninteractive

View File

@@ -0,0 +1,78 @@
# -*- coding: utf-8 -*-
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin
export PATH
export DEBIAN_FRONTEND=noninteractive
# https://downloads.mysql.com/archives/community/
curPath=`pwd`
rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
sysName=`uname`
myDir=${serverPath}/source/mysql-community
OS_ARCH=`arch`
MYSQL_VER=9.0.11
SUFFIX_NAME=${MYSQL_VER}-macos14-arm64
COMMUNITY_INSTALL()
{
########
mkdir -p $myDir
mkdir -p $serverPath/mysql-community
# https://cdn.mysql.com/archives/mysql-9.0/mysql-9.0.1-macos14-arm64.tar.gz
if [ ! -f ${myDir}/mysql-${SUFFIX_NAME}.tar.gz ];then
wget --no-check-certificate -O ${myDir}/mysql-${SUFFIX_NAME}.tar.gz https://cdn.mysql.com/archives/mysql-9.0/mysql-${SUFFIX_NAME}.tar.gz
fi
if [ -d ${myDir} ];then
cd ${myDir} && tar -zxvf ${myDir}/mysql-${SUFFIX_NAME}.tar.gz
cp -rf ${myDir}/mysql-${SUFFIX_NAME}/* $serverPath/mysql-community
fi
# 测试时可关闭
# rm -rf $myDir/mysql-${SUFFIX_NAME}
#######
}
COMMUNITY_UNINSTALL()
{
###
rm -rf $myDir/mysql-${SUFFIX_NAME}
# apt remove -y mysql-server
###
}
Install_mysql()
{
echo '正在安装脚本文件...'
COMMUNITY_INSTALL
if [ "$?" = "0" ];then
mkdir -p $serverPath/mysql-community
echo '9.0' > $serverPath/mysql-community/version.pl
echo '安装完成'
else
echo '9.0' > $serverPath/mysql-community/version.pl
echo "暂时不支持该系统"
fi
}
Uninstall_mysql()
{
COMMUNITY_UNINSTALL
rm -rf $serverPath/mysql-community
echo '卸载完成'
}
action=$1
if [ "${1}" = 'install' ];then
Install_mysql
else
Uninstall_mysql
fi

View File

@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin
export PATH
export DEBIAN_FRONTEND=noninteractive

View File

@@ -0,0 +1,78 @@
# -*- coding: utf-8 -*-
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin
export PATH
export DEBIAN_FRONTEND=noninteractive
# https://downloads.mysql.com/archives/community/
curPath=`pwd`
rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
sysName=`uname`
myDir=${serverPath}/source/mysql-community
OS_ARCH=`arch`
MYSQL_VER=9.1.0
SUFFIX_NAME=${MYSQL_VER}-macos14-arm64
COMMUNITY_INSTALL()
{
########
mkdir -p $myDir
mkdir -p $serverPath/mysql-community
# https://cdn.mysql.com/archives/mysql-9.1/mysql-9.1.0-macos14-arm64.tar.gz
if [ ! -f ${myDir}/mysql-${SUFFIX_NAME}.tar.gz ];then
wget --no-check-certificate -O ${myDir}/mysql-${SUFFIX_NAME}.tar.gz https://cdn.mysql.com/archives/mysql-9.1/mysql-${SUFFIX_NAME}.tar.gz
fi
if [ -d ${myDir} ];then
cd ${myDir} && tar -zxvf ${myDir}/mysql-${SUFFIX_NAME}.tar.gz
cp -rf ${myDir}/mysql-${SUFFIX_NAME}/* $serverPath/mysql-community
fi
# 测试时可关闭
# rm -rf $myDir/mysql-${SUFFIX_NAME}
#######
}
COMMUNITY_UNINSTALL()
{
###
rm -rf $myDir/mysql-${SUFFIX_NAME}
# apt remove -y mysql-server
###
}
Install_mysql()
{
echo '正在安装脚本文件...'
COMMUNITY_INSTALL
if [ "$?" = "0" ];then
mkdir -p $serverPath/mysql-community
echo '9.1' > $serverPath/mysql-community/version.pl
echo '安装完成'
else
echo '9.1' > $serverPath/mysql-community/version.pl
echo "暂时不支持该系统"
fi
}
Uninstall_mysql()
{
COMMUNITY_UNINSTALL
rm -rf $serverPath/mysql-community
echo '卸载完成'
}
action=$1
if [ "${1}" = 'install' ];then
Install_mysql
else
Uninstall_mysql
fi

View File

@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin
export PATH
export DEBIAN_FRONTEND=noninteractive

View File

@@ -0,0 +1,78 @@
# -*- coding: utf-8 -*-
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin
export PATH
export DEBIAN_FRONTEND=noninteractive
# https://downloads.mysql.com/archives/community/
curPath=`pwd`
rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
sysName=`uname`
myDir=${serverPath}/source/mysql-community
OS_ARCH=`arch`
MYSQL_VER=9.2.0
SUFFIX_NAME=${MYSQL_VER}-macos14-arm64
COMMUNITY_INSTALL()
{
########
mkdir -p $myDir
mkdir -p $serverPath/mysql-community
# https://cdn.mysql.com/archives/mysql-9.2/mysql-9.2.0-macos14-arm64.tar.gz
if [ ! -f ${myDir}/mysql-${SUFFIX_NAME}.tar.gz ];then
wget --no-check-certificate -O ${myDir}/mysql-${SUFFIX_NAME}.tar.gz https://cdn.mysql.com/archives/mysql-9.2/mysql-${SUFFIX_NAME}.tar.gz
fi
if [ -d ${myDir} ];then
cd ${myDir} && tar -zxvf ${myDir}/mysql-${SUFFIX_NAME}.tar.gz
cp -rf ${myDir}/mysql-${SUFFIX_NAME}/* $serverPath/mysql-community
fi
# 测试时可关闭
# rm -rf $myDir/mysql-${SUFFIX_NAME}
#######
}
COMMUNITY_UNINSTALL()
{
###
rm -rf $myDir/mysql-${SUFFIX_NAME}
# apt remove -y mysql-server
###
}
Install_mysql()
{
echo '正在安装脚本文件...'
COMMUNITY_INSTALL
if [ "$?" = "0" ];then
mkdir -p $serverPath/mysql-community
echo '9.2' > $serverPath/mysql-community/version.pl
echo '安装完成'
else
echo '9.2' > $serverPath/mysql-community/version.pl
echo "暂时不支持该系统"
fi
}
Uninstall_mysql()
{
COMMUNITY_UNINSTALL
rm -rf $serverPath/mysql-community
echo '卸载完成'
}
action=$1
if [ "${1}" = 'install' ];then
Install_mysql
else
Uninstall_mysql
fi

View File

@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin
export PATH
export DEBIAN_FRONTEND=noninteractive

View File

@@ -0,0 +1,79 @@
# -*- coding: utf-8 -*-
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin
export PATH
export DEBIAN_FRONTEND=noninteractive
# https://downloads.mysql.com/archives/community/
curPath=`pwd`
rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
sysName=`uname`
myDir=${serverPath}/source/mysql-community
OS_ARCH=`arch`
MYSQL_VER=9.3.0
SUFFIX_NAME=${MYSQL_VER}-macos15-arm64
COMMUNITY_INSTALL()
{
########
mkdir -p $myDir
mkdir -p $serverPath/mysql-community
# Linux - Generic
# https://cdn.mysql.com/archives/mysql-9.3/mysql-9.3.0-macos15-arm64.tar.gz
if [ ! -f ${myDir}/mysql-${SUFFIX_NAME}.tar.gz ];then
wget --no-check-certificate -O ${myDir}/mysql-${SUFFIX_NAME}.tar.gz https://cdn.mysql.com/archives/mysql-9.3/mysql-${SUFFIX_NAME}.tar.gz
fi
if [ -d ${myDir} ];then
cd ${myDir} && tar -zxvf ${myDir}/mysql-${SUFFIX_NAME}.tar.gz
cp -rf ${myDir}/mysql-${SUFFIX_NAME}/* $serverPath/mysql-community
fi
# 测试时可关闭
# rm -rf $myDir/mysql-${SUFFIX_NAME}
#######
}
COMMUNITY_UNINSTALL()
{
###
rm -rf $myDir/mysql-${SUFFIX_NAME}
# apt remove -y mysql-server
###
}
Install_mysql()
{
echo '正在安装脚本文件...'
COMMUNITY_INSTALL
if [ "$?" = "0" ];then
mkdir -p $serverPath/mysql-community
echo '9.3' > $serverPath/mysql-community/version.pl
echo '安装完成'
else
echo '9.3' > $serverPath/mysql-community/version.pl
echo "暂时不支持该系统"
fi
}
Uninstall_mysql()
{
COMMUNITY_UNINSTALL
rm -rf $serverPath/mysql-community
echo '卸载完成'
}
action=$1
if [ "${1}" = 'install' ];then
Install_mysql
else
Uninstall_mysql
fi

View File

@@ -0,0 +1,82 @@
# -*- coding: utf-8 -*-
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin
export PATH
export DEBIAN_FRONTEND=noninteractive
# https://downloads.mysql.com/archives/community/
curPath=`pwd`
rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
sysName=`uname`
myDir=${serverPath}/source/mysql-community
OS_ARCH=`arch`
MYSQL_VER=9.7.4
SUFFIX_NAME=${MYSQL_VER}-linux-glibc2.28-${OS_ARCH}
# cd /www/server/mdserver-web/plugins/mysql-community && bash install.sh install 9.7
# cd /www/server/mdserver-web && python3 /www/server/mdserver-web/plugins/mysql-community/index.py start 9.7
COMMUNITY_INSTALL()
{
########
mkdir -p $myDir
mkdir -p $serverPath/mysql-community
# Linux - Generic
# https://cdn.mysql.com//Downloads/MySQL-9.7/mysql-9.7.4-linux-glibc2.28-x86_64.tar.xz
# https://cdn.mysql.com//Downloads/MySQL-9.7/mysql-${SUFFIX_NAME}.tar.xz
if [ ! -f ${myDir}/mysql-${SUFFIX_NAME}.tar.xz ];then
wget --no-check-certificate -O ${myDir}/mysql-${SUFFIX_NAME}.tar.xz https://cdn.mysql.com//Downloads/MySQL-9.7/mysql-${SUFFIX_NAME}.tar.xz
fi
if [ -d ${myDir} ];then
cd ${myDir} && tar -Jxf ${myDir}/mysql-${SUFFIX_NAME}.tar.xz
cp -rf ${myDir}/mysql-${SUFFIX_NAME}/* $serverPath/mysql-community
fi
# 测试时可关闭
rm -rf $myDir/mysql-${SUFFIX_NAME}
#######
}
COMMUNITY_UNINSTALL()
{
###
rm -rf $myDir/mysql-${SUFFIX_NAME}
# apt remove -y mysql-server
###
}
Install_mysql()
{
echo '正在安装脚本文件...'
COMMUNITY_INSTALL
if [ "$?" = "0" ];then
mkdir -p $serverPath/mysql-community
echo '9.7' > $serverPath/mysql-community/version.pl
echo '安装完成'
else
echo '9.7' > $serverPath/mysql-community/version.pl
echo "暂时不支持该系统"
fi
}
Uninstall_mysql()
{
COMMUNITY_UNINSTALL
rm -rf $serverPath/mysql-community
echo '卸载完成'
}
action=$1
if [ "${1}" = 'install' ];then
Install_mysql
else
Uninstall_mysql
fi

View File

@@ -0,0 +1,78 @@
# -*- coding: utf-8 -*-
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin
export PATH
export DEBIAN_FRONTEND=noninteractive
# https://downloads.mysql.com/archives/community/
curPath=`pwd`
rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
sysName=`uname`
myDir=${serverPath}/source/mysql-community
OS_ARCH=`arch`
MYSQL_VER=9.7.4
SUFFIX_NAME=${MYSQL_VER}-macos15-arm64
COMMUNITY_INSTALL()
{
########
mkdir -p $myDir
mkdir -p $serverPath/mysql-community
# https://cdn.mysql.com//Downloads/MySQL-9.7/mysql-9.7.4-macos15-arm64.tar.gz
if [ ! -f ${myDir}/mysql-${SUFFIX_NAME}.tar.gz ];then
wget --no-check-certificate -O ${myDir}/mysql-${SUFFIX_NAME}.tar.gz https://cdn.mysql.com//Downloads/MySQL-9.7/mysql-${SUFFIX_NAME}.tar.gz
fi
if [ -d ${myDir} ];then
cd ${myDir} && tar -zxvf ${myDir}/mysql-${SUFFIX_NAME}.tar.gz
cp -rf ${myDir}/mysql-${SUFFIX_NAME}/* $serverPath/mysql-community
fi
# 测试时可关闭
# rm -rf $myDir/mysql-${SUFFIX_NAME}
#######
}
COMMUNITY_UNINSTALL()
{
###
rm -rf $myDir/mysql-${SUFFIX_NAME}
# apt remove -y mysql-server
###
}
Install_mysql()
{
echo '正在安装脚本文件...'
COMMUNITY_INSTALL
if [ "$?" = "0" ];then
mkdir -p $serverPath/mysql-community
echo '9.7' > $serverPath/mysql-community/version.pl
echo '安装完成'
else
echo '9.7' > $serverPath/mysql-community/version.pl
echo "暂时不支持该系统"
fi
}
Uninstall_mysql()
{
COMMUNITY_UNINSTALL
rm -rf $serverPath/mysql-community
echo '卸载完成'
}
action=$1
if [ "${1}" = 'install' ];then
Install_mysql
else
Uninstall_mysql
fi

View File

@@ -0,0 +1,121 @@
[client]
user = root
#password = your_password
port = 3306
socket = {$SERVER_APP_PATH}/mysql.sock
default-character-set = UTF8MB4
[mysqld]
!include {$SERVER_APP_PATH}/etc/mode/classic.cnf
authentication_policy=caching_sha2_password
pid-file = {$SERVER_APP_PATH}/data/mysql.pid
user = mysql
port = 3306
socket = {$SERVER_APP_PATH}/mysql.sock
basedir = {$SERVER_APP_PATH}
datadir = {$SERVER_APP_PATH}/data
log-error = {$SERVER_APP_PATH}/data/error.log
server-id = {$SERVER_ID}
#sql-mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
default_storage_engine = InnoDB
key_buffer_size = 8M
table_open_cache = 32
sort_buffer_size = 256K
net_buffer_length = 4K
read_buffer_size = 128K
read_rnd_buffer_size = 256K
myisam_sort_buffer_size = 4M
thread_cache_size = 4
lower_case_table_names=1
tmp_table_size = 8M
character-set-server = UTF8MB4
max_connections = 500
max_connect_errors = 100
open_files_limit = 2560
max_allowed_packet = 128M
skip_name_resolve=1
#skip-networking
#skip-external-locking
#loose-skip-innodb
#skip-grant-tables
#skip-log-bin
#disable-log-bin
#skip-slave-start
log-bin=mysql-bin
slow_query_log=1
slow-query-log-file={$SERVER_APP_PATH}/data/mysql-slow.log
long_query_time=10
#log_queries_not_using_indexes=1
#log_slow_admin_statements=1
#log_slow_replica_statements=1
binlog_expire_logs_seconds=604800
relay-log=mdserver
relay-log-index=mdserver
#多主设置
#auto_increment_offset=2
#auto_increment_increment=2
#master
#sync_binlog=1
#binlog-do-db
binlog-ignore-db = test
binlog-ignore-db = mysql
binlog-ignore-db = information_schema
binlog-ignore-db = performance_schema
#slave
log_replica_updates = 1
# Prevent replication from starting automatically with MySQL
#skip_replica_start = 1
#replicate-do-db
replica_skip_errors=1062,1396
replicate-ignore-db = information_schema
replicate-ignore-db = performance_schema
replicate-ignore-db = mysql
replicate-ignore-db = test
replicate-wild-ignore-table = mysql.%
replicate-wild-ignore-table = information_schema.%
replicate-wild-ignore-table = performance_schema.%
replicate-wild-ignore-table = sys.%
innodb_data_home_dir = {$SERVER_APP_PATH}/data
innodb_data_file_path = ibdata1:10M:autoextend
innodb_log_group_home_dir = {$SERVER_APP_PATH}/data
innodb_buffer_pool_size = 16M
#innodb_log_file_size = 5M
innodb_redo_log_capacity = 4G
innodb_log_buffer_size = 8M
innodb_flush_log_at_trx_commit = 1
innodb_lock_wait_timeout = 120
innodb_max_dirty_pages_pct = 90
innodb_read_io_threads = 1
innodb_write_io_threads = 1
innodb_file_per_table=1
secure-file-priv={$SERVER_APP_PATH}/tmp
[mysqldump]
quick
[mysql]
no-auto-rehash
[myisamchk]
key_buffer_size = 20M
sort_buffer_size = 20M
read_buffer = 2M
write_buffer = 2M
[mysqlhotcopy]
interactive-timeout

View File

@@ -0,0 +1,121 @@
[client]
user = root
#password = your_password
port = 3306
socket = {$SERVER_APP_PATH}/mysql.sock
default-character-set = UTF8MB4
[mysqld]
!include {$SERVER_APP_PATH}/etc/mode/classic.cnf
authentication_policy=caching_sha2_password
pid-file = {$SERVER_APP_PATH}/data/mysql.pid
user = mysql
port = 3306
socket = {$SERVER_APP_PATH}/mysql.sock
basedir = {$SERVER_APP_PATH}
datadir = {$SERVER_APP_PATH}/data
log-error = {$SERVER_APP_PATH}/data/error.log
server-id = {$SERVER_ID}
#sql-mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
default_storage_engine = InnoDB
key_buffer_size = 8M
table_open_cache = 32
sort_buffer_size = 256K
net_buffer_length = 4K
read_buffer_size = 128K
read_rnd_buffer_size = 256K
myisam_sort_buffer_size = 4M
thread_cache_size = 4
lower_case_table_names=1
tmp_table_size = 8M
character-set-server = UTF8MB4
max_connections = 500
max_connect_errors = 100
open_files_limit = 2560
max_allowed_packet = 128M
skip_name_resolve=1
#skip-networking
#skip-external-locking
#loose-skip-innodb
#skip-grant-tables
#skip-log-bin
#disable-log-bin
#skip-slave-start
log-bin=mysql-bin
slow_query_log=1
slow-query-log-file={$SERVER_APP_PATH}/data/mysql-slow.log
long_query_time=10
#log_queries_not_using_indexes=1
#log_slow_admin_statements=1
#log_slow_replica_statements=1
binlog_expire_logs_seconds=604800
relay-log=mdserver
relay-log-index=mdserver
#多主设置
#auto_increment_offset=2
#auto_increment_increment=2
#master
#sync_binlog=1
#binlog-do-db
binlog-ignore-db = test
binlog-ignore-db = mysql
binlog-ignore-db = information_schema
binlog-ignore-db = performance_schema
#slave
log_replica_updates = 1
# Prevent replication from starting automatically with MySQL
#skip_replica_start = 1
#replicate-do-db
replica_skip_errors=1062,1396
replicate-ignore-db = information_schema
replicate-ignore-db = performance_schema
replicate-ignore-db = mysql
replicate-ignore-db = test
replicate-wild-ignore-table = mysql.%
replicate-wild-ignore-table = information_schema.%
replicate-wild-ignore-table = performance_schema.%
replicate-wild-ignore-table = sys.%
innodb_data_home_dir = {$SERVER_APP_PATH}/data
innodb_data_file_path = ibdata1:10M:autoextend
innodb_log_group_home_dir = {$SERVER_APP_PATH}/data
innodb_buffer_pool_size = 16M
#innodb_log_file_size = 5M
innodb_redo_log_capacity = 4G
innodb_log_buffer_size = 8M
innodb_flush_log_at_trx_commit = 1
innodb_lock_wait_timeout = 120
innodb_max_dirty_pages_pct = 90
innodb_read_io_threads = 1
innodb_write_io_threads = 1
innodb_file_per_table=1
secure-file-priv={$SERVER_APP_PATH}/tmp
[mysqldump]
quick
[mysql]
no-auto-rehash
[myisamchk]
key_buffer_size = 20M
sort_buffer_size = 20M
read_buffer = 2M
write_buffer = 2M
[mysqlhotcopy]
interactive-timeout

View File

@@ -82,6 +82,11 @@ replicate-ignore-db = performance_schema
replicate-ignore-db = mysql
replicate-ignore-db = test
replicate-wild-ignore-table = mysql.%
replicate-wild-ignore-table = information_schema.%
replicate-wild-ignore-table = performance_schema.%
replicate-wild-ignore-table = sys.%
innodb_data_home_dir = {$SERVER_APP_PATH}/data
innodb_data_file_path = ibdata1:10M:autoextend

View File

@@ -85,6 +85,11 @@ replicate-ignore-db = performance_schema
replicate-ignore-db = mysql
replicate-ignore-db = test
replicate-wild-ignore-table = mysql.%
replicate-wild-ignore-table = information_schema.%
replicate-wild-ignore-table = performance_schema.%
replicate-wild-ignore-table = sys.%
innodb_data_home_dir = {$SERVER_APP_PATH}/data
innodb_data_file_path = ibdata1:10M:autoextend

View File

@@ -87,6 +87,11 @@ replicate-ignore-db = performance_schema
replicate-ignore-db = mysql
replicate-ignore-db = test
replicate-wild-ignore-table = mysql.%
replicate-wild-ignore-table = information_schema.%
replicate-wild-ignore-table = performance_schema.%
replicate-wild-ignore-table = sys.%
master_info_repository = table
relay_log_info_repository = table

View File

@@ -87,6 +87,11 @@ replicate-ignore-db = performance_schema
replicate-ignore-db = mysql
replicate-ignore-db = test
replicate-wild-ignore-table = mysql.%
replicate-wild-ignore-table = information_schema.%
replicate-wild-ignore-table = performance_schema.%
replicate-wild-ignore-table = sys.%
innodb_data_home_dir = {$SERVER_APP_PATH}/data
innodb_data_file_path = ibdata1:10M:autoextend

View File

@@ -86,6 +86,11 @@ replicate-ignore-db = performance_schema
replicate-ignore-db = mysql
replicate-ignore-db = test
replicate-wild-ignore-table = mysql.%
replicate-wild-ignore-table = information_schema.%
replicate-wild-ignore-table = performance_schema.%
replicate-wild-ignore-table = sys.%
innodb_data_home_dir = {$SERVER_APP_PATH}/data
innodb_data_file_path = ibdata1:10M:autoextend

View File

@@ -86,6 +86,11 @@ replicate-ignore-db = performance_schema
replicate-ignore-db = mysql
replicate-ignore-db = test
replicate-wild-ignore-table = mysql.%
replicate-wild-ignore-table = information_schema.%
replicate-wild-ignore-table = performance_schema.%
replicate-wild-ignore-table = sys.%
innodb_data_home_dir = {$SERVER_APP_PATH}/data
innodb_data_file_path = ibdata1:10M:autoextend

View File

@@ -83,6 +83,10 @@ replicate-ignore-db = performance_schema
replicate-ignore-db = mysql
replicate-ignore-db = test
replicate-wild-ignore-table = mysql.%
replicate-wild-ignore-table = information_schema.%
replicate-wild-ignore-table = performance_schema.%
replicate-wild-ignore-table = sys.%
innodb_data_home_dir = {$SERVER_APP_PATH}/data
innodb_data_file_path = ibdata1:10M:autoextend

View File

@@ -83,6 +83,10 @@ replicate-ignore-db = performance_schema
replicate-ignore-db = mysql
replicate-ignore-db = test
replicate-wild-ignore-table = mysql.%
replicate-wild-ignore-table = information_schema.%
replicate-wild-ignore-table = performance_schema.%
replicate-wild-ignore-table = sys.%
innodb_data_home_dir = {$SERVER_APP_PATH}/data
innodb_data_file_path = ibdata1:10M:autoextend

View File

@@ -83,6 +83,10 @@ replicate-ignore-db = performance_schema
replicate-ignore-db = mysql
replicate-ignore-db = test
replicate-wild-ignore-table = mysql.%
replicate-wild-ignore-table = information_schema.%
replicate-wild-ignore-table = performance_schema.%
replicate-wild-ignore-table = sys.%
innodb_data_home_dir = {$SERVER_APP_PATH}/data
innodb_data_file_path = ibdata1:10M:autoextend

View File

@@ -83,6 +83,10 @@ replicate-ignore-db = performance_schema
replicate-ignore-db = mysql
replicate-ignore-db = test
replicate-wild-ignore-table = mysql.%
replicate-wild-ignore-table = information_schema.%
replicate-wild-ignore-table = performance_schema.%
replicate-wild-ignore-table = sys.%
innodb_data_home_dir = {$SERVER_APP_PATH}/data
innodb_data_file_path = ibdata1:10M:autoextend

Some files were not shown because too many files have changed in this diff Show More