I've discovered that MySQL has multiple row formats, and it's possible to specify this or change it. Also, the default ROW_FORMAT has apparently changed over time with MySQL versions, which is understandable.
However, I can't find anywhere that says how to find out what the ROW_FORMAT of an existing table is! My database has been around for years, from older versions of MySQL, and I want to make sure I'm not using a poorly performing ancient disk format.
How do I find out the ROW_FORMAT of a table in MySQL?
Information schema offers a wealth of information.
SELECT row_format FROM information_schema.tables
WHERE table_schema="YOUR DB" AND table_name="YOUR TABLE" LIMIT 1;
2014.06.19 - Mild Update
The following query will give you the row format of all tables in the current database:
SELECT `table_name`, `row_format`
FROM `information_schema`.`tables`
WHERE `table_schema`=DATABASE();
With following query:
show table status like 'table_name';
Related
i want to change table character set from 'utf8' to 'utf8mb4'
but each column has own character set setting(utf8)
so i need to change column character set to 'Table Default', but locking is the problem
help me to change column character set without table locking
there is over 100,000,000 rows in table
"Character set" is the encoding of the characters in bytes.
"Collation" is how to sort characters.
An INDEX on a VARCHAR is sorted by its collation, so changing the collation of a column requires rebuilding an index -- a non-trivial operation.
The difference between utf8 and utf8mb4 is relatively minor, but I don't think MySQL (hence RDS) has made a special case of that.
ALTER TABLE t CONVERT TO utf8mb4; sounds like the operation that you desire. That requires ALGORITHM=COPY, so it is 'locking'.
Look into pt-online-schema-change and gh-ost as a way of altering a table, even when it needs to "copy". These are essentially non-blocking. However, I do not know if they can be used with RDS. Also, because of JOINs and other cases where one table may need to be consistent with another, those tools may not be practical.
Another approach... Add another column(s); change your code to use both the old and new column(s). Meanwhile, gradually copy the old values to the new column(s); when this is finished, change your code again -- this time to use the new column(s) instead of the old. At some later date, worry about dropping the dead column(s).
Recent versions of MySQL have made significant changes in the speed of ALTER, so be sure to study what version RDS is derived from. In 5.6, ADD COLUMN can use ALGORITHM=INPLACE; in 8.0, ALGORITHM=INSTANT. I think either of those is non-"locking" for your purposes. (DROP COLUMN is not cheap; the issues with JOIN and rebuilding indexes are still up in the air.)
If you try one of these techniques, I strongly recommend you build a table with at least a million rows and try out all the steps (alter add, join, recreate index, alter drop column, etc) to verify what parts are "fast enough" and/or "non-locking".
While using phpMyAdmin I noticed suddenly that the table I frequently used had shifted to a different page, it used to be on page 2 where now it is on page 3. I'm the only one working on this database and find this quite peculiar.
There are quite a number of tables in this database so one or two new ones aren't going to stand out to me.
Is there somehow I can list the tables in this database in chronological order of being added?
Your (and my) first inclination might be to use SHOW TABLES, but alas there does not appear to be a way to do an ORDER BY, q.v. the official MySQL documentation. However, you can query information_schema.tables and order by the update_time:
SELECT table_name
FROM information_schema.tables
WHERE table_schema = 'db_name'
ORDER BY update_time DESC;
The above query will give you all tables in the db_name database sorted with the most recent first.
I just saw that MySQL 5.5 offers utf8_general_mysql500_ci as collation.
What is the difference to other collations like utf8_general_ci?
Should I better use utf8_general_mysql500_ci?
As documented under Changes in MySQL 5.5.21:
New utf8_general_mysql500_ci and ucs2_general_mysql500_ci collations have been added that preserve the behavior of utf8_general_ci and ucs2_general_ci from versions of MySQL previous to 5.1.24. Bug #27877 corrected an error in the original collations but introduced an incompatibility for columns that contain German 'ß' LATIN SMALL LETTER SHARP S. (As a result of the fix, that character compares equal to characters with which it previously compared different.) A symptom of the problem after upgrading to MySQL 5.1.24 or newer from a version older than 5.1.24 is that CHECK TABLE produces this error:
Table upgrade required.
Please do "REPAIR TABLE `t`" or dump/reload to fix it!
Unfortunately, REPAIR TABLE could not fix the problem. The new collations permit older tables created before MySQL 5.1.24 to be upgraded to current versions of MySQL.
To convert an affected table after a binary upgrade that leaves the table files in place, alter the table to use the new collation. Suppose that the table t1 contains one or more problematic utf8 columns. To convert the table at the table level, use a statement like this:
ALTER TABLE t1
CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_mysql500_ci;
To apply the change on a column-specific basis, use a statement like this (be sure to repeat the column definition as originally specified except for the COLLATE clause):
ALTER TABLE t1
MODIFY c1 CHAR(N) CHARACTER SET utf8 COLLATE utf8_general_mysql500_ci;
To upgrade the table using a dump and reload procedure, dump the table using mysqldump, modify the CREATE TABLE statement in the dump file to use the new collation, and reload the table.
After making the appropriate changes, CHECK TABLE should report no error.
For more information, see Checking Whether Tables or Indexes Must Be Rebuilt, and Rebuilding or Repairing Tables or Indexes. (Bug #43593, Bug #11752408)
What is the MySQL statement to alter the row_format to dynamic?
I am not sure how I am supposed to do it (i.e. using the information_schema or by using a table ALTER).
try
ALTER TABLE `test` ROW_FORMAT=DYNAMIC;
The method I've used, based on the current Oracle docs, is because the COMPACT tables I have were only set based on the default, which has now changed. This is on a MariaDB 10.2 system for me, but will work on modern MySQL systems.
Specifically, ensure default is DYNAMIC (or the format you need):
SET GLOBAL innodb_default_row_format=DYNAMIC;
Then OPTIMIZE the tables you need to change;
OPTIMIZE TABLE database.tablename;
This works, because the row_format is updated to the server default on an "operation that rebuilds a table silently", to quote the documentation.
In MySQL, there is no way to specify a storage engine for a certain database, only for single tables. However, you can specify a storage engine to be used during one session with:
SET storage_engine=InnoDB;
So you don't have to specify it for each table.
How do I confirm, if indeed all the tables are using InnoDB?
If you use SHOW CREATE TABLE, you have to parse the engine out of the query.
Selecting from the INFORMATION_SCHEMA database is poor practice, as the devs reserve the right to change its schema at any time (though it is unlikely).
The correct query to use is SHOW TABLE STATUS - you can get information on all the tables in a database:
SHOW TABLE STATUS FROM `database`;
Or for a specific table:
SHOW TABLE STATUS FROM `database` LIKE 'tablename';
One of the columns you will get back is Engine.
SELECT * FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'db name' AND ENGINE != 'InnoDB'
show create table <table> should do the trick.