source: moodle/trunk/fuentes/admin/cli/mysql_compressed_rows.php @ 136

Last change on this file since 136 was 136, checked in by mabarracus, 4 years ago

Ported code to xenial

File size: 6.5 KB
Line 
1<?php
2// This file is part of Moodle - http://moodle.org/
3//
4// Moodle is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// Moodle is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
16
17/**
18 * MySQL table row compression tool tool.
19 *
20 * @package   core
21 * @copyright 2014 Totara Learning Solutions Ltd {@link http://www.totaralms.com/}
22 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23 * @author    Petr Skoda <petr.skoda@totaralms.com>
24 */
25
26define('CLI_SCRIPT', true);
27
28require(dirname(__FILE__).'/../../config.php');
29require_once($CFG->libdir . '/clilib.php');
30
31if ($DB->get_dbfamily() !== 'mysql') {
32    cli_error('This script is used for MySQL databases only.');
33}
34
35$engine = strtolower($DB->get_dbengine());
36if ($engine !== 'innodb' and $engine !== 'xtradb') {
37    cli_error('This script is for MySQL servers using InnoDB or XtraDB engines only.');
38}
39
40list($options, $unrecognized) = cli_get_params(
41    array('help' => false, 'info' => false, 'list' => false, 'fix' => false, 'showsql' => false),
42    array('h' => 'help', 'i' => 'info', 'l' => 'list', 'f' => 'fix', 's' => 'showsql')
43);
44
45if ($unrecognized) {
46    $unrecognized = implode("\n  ", $unrecognized);
47    cli_error(get_string('cliunknowoption', 'admin', $unrecognized));
48}
49
50$help =
51    "Script for detection of row size problems in MySQL InnoDB tables.
52
53By default InnoDB storage table is using legacy Antelope file format
54which has major restriction on database row size.
55Use this script to detect and fix database tables with potential data
56overflow problems.
57
58Options:
59-i, --info            Show database information
60-l, --list            List problematic tables
61-f, --fix             Attempt to fix all tables (requires SUPER privilege)
62-s, --showsql         Print SQL statements for fixing of tables
63-h, --help            Print out this help
64
65Example:
66\$ sudo -u www-data /usr/bin/php admin/cli/mysql_compressed_rows.php -l
67";
68
69/** @var mysql_sql_generator $generator */
70$generator = $DB->get_manager()->generator;
71
72$info = $DB->get_server_info();
73$filepertable = $DB->get_record_sql("SHOW VARIABLES LIKE 'innodb_file_per_table'");
74$filepertable = $filepertable ? $filepertable->value : '';
75$fileformat = $DB->get_record_sql("SHOW VARIABLES LIKE 'innodb_file_format'");
76$fileformat = $fileformat ? $fileformat->value : '';
77$prefix = $DB->get_prefix();
78$database = $CFG->dbname;
79
80if (!empty($options['info'])) {
81    echo "Database version:      " . $info['description'] . "\n";
82    echo "Database name:         $database\n";
83    echo "Database engine:       " . $DB->get_dbengine() . "\n";
84    echo "innodb_file_per_table: $filepertable\n";
85    echo "innodb_file_format:    $fileformat\n";
86
87    exit(0);
88
89} else if (!empty($options['list'])) {
90    $problem = false;
91    foreach ($DB->get_tables(false) as $table) {
92        $columns = $DB->get_columns($table, false);
93        $size = $generator->guess_antolope_row_size($columns);
94        $format = $DB->get_row_format($table);
95        if ($size <= $generator::ANTELOPE_MAX_ROW_SIZE) {
96            continue;
97        }
98
99        echo str_pad($prefix . $table, 32, ' ', STR_PAD_RIGHT);
100        echo str_pad($format, 11, ' ', STR_PAD_RIGHT);
101
102        if ($format === 'Compact' or $format === 'Redundant') {
103            $problem = true;
104            echo " (needs fixing)\n";
105
106        } else if ($format !== 'Compressed' and $format !== 'Dynamic') {
107            echo " (unknown)\n";
108
109        } else {
110            echo "\n";
111        }
112    }
113
114    if ($problem) {
115        exit(1);
116    }
117    exit(0);
118
119} else if (!empty($options['fix'])) {
120    $fixtables = array();
121    foreach ($DB->get_tables(false) as $table) {
122        $columns = $DB->get_columns($table, false);
123        $size = $generator->guess_antolope_row_size($columns);
124        $format = $DB->get_row_format($table);
125        if ($size <= $generator::ANTELOPE_MAX_ROW_SIZE) {
126            continue;
127        }
128        if ($format === 'Compact' or $format === 'Redundant') {
129            $fixtables[$table] = $table;
130        }
131    }
132
133    if (!$fixtables) {
134        echo "No changes necessary\n";
135        exit(0);
136    }
137
138    if ($filepertable !== 'ON') {
139        try {
140            $DB->execute("SET GLOBAL innodb_file_per_table=1");
141        } catch (dml_exception $e) {
142            echo "Cannot enable GLOBAL innodb_file_per_table setting, use --showsql option and execute the statements manually.";
143            throw $e;
144        }
145    }
146    if ($fileformat !== 'Barracuda') {
147        try {
148            $DB->execute("SET GLOBAL innodb_file_format=Barracuda");
149        } catch (dml_exception $e) {
150            echo "Cannot change GLOBAL innodb_file_format setting, use --showsql option and execute the statements manually.";
151            throw $e;
152        }
153    }
154
155    if (!$DB->is_compressed_row_format_supported(false)) {
156        echo "MySQL server is not compatible with compressed row format.";
157        exit(1);
158    }
159
160    foreach ($fixtables as $table) {
161        $DB->change_database_structure("ALTER TABLE {$prefix}$table ROW_FORMAT=Compressed");
162        echo str_pad($prefix . $table, 32, ' ', STR_PAD_RIGHT) . " ... Compressed\n";
163    }
164
165    exit(0);
166
167} else if (!empty($options['showsql'])) {
168    $fixtables = array();
169
170    foreach ($DB->get_tables(false) as $table) {
171        $columns = $DB->get_columns($table, false);
172        $size = $generator->guess_antolope_row_size($columns);
173        $format = $DB->get_row_format($table);
174        if ($size <= $generator::ANTELOPE_MAX_ROW_SIZE) {
175            continue;
176        }
177        if ($format === 'Compact' or $format === 'Redundant') {
178            $fixtables[$table] = $table;
179        }
180    }
181    if (!$fixtables) {
182        echo "No changes necessary\n";
183        exit(0);
184    }
185
186    echo "Copy the following SQL statements and execute them using account with SUPER privilege:\n\n";
187    echo "USE $database;\n";
188    echo "SET SESSION sql_mode=STRICT_ALL_TABLES;\n";
189    echo "SET GLOBAL innodb_file_per_table=1;\n";
190    echo "SET GLOBAL innodb_file_format=Barracuda;\n";
191    foreach ($fixtables as $table) {
192        echo "ALTER TABLE {$prefix}$table ROW_FORMAT=Compressed;\n";
193    }
194    echo "\n";
195    exit(0);
196
197} else {
198    echo $help;
199    die;
200}
201
202
Note: See TracBrowser for help on using the repository browser.