RE:NODE
Browse hosting

Databases15 min read

phpMyAdmin import and export: limits, charsets and fixes

How to export and import a database in phpMyAdmin: the options that matter, upload limits, utf8mb4, and the error numbers you will hit.

0 readers

To take a copy of a database: Export, choose Custom, format SQL, tick gzipped under compression, press Go. To put one back: Import, pick the file, check that the character set says utf-8, press Go. That is the whole job when it works, and it works most of the time. When it does not, it is almost always one of three things: the file is larger than the upload limit printed on the Import page, the character set of the file does not match the character set of the target, or the dump contains an object your database user is not permitted to create. This guide covers the two tabs in detail and then each of those failures in turn.

phpMyAdmin is a web interface, and web interfaces have timeouts and upload ceilings that a command line does not. That single sentence explains most of the frustration people have with it. Knowing where the ceiling is, and knowing the three ways around it, turns a two-hour fight into a five-minute job.

What phpMyAdmin is, and what it is not#

phpMyAdmin is a PHP application that talks to a MySQL-compatible database server on your behalf. It is not the database. It has no storage of its own, it holds no copy of your data, and removing it removes nothing. Everything it does is a query it could have typed for you, which is why the SQL tab exists and why the button labelled "Show SQL" under most operations is worth pressing at least once.

Two consequences follow, and both matter for import and export:

  • Everything runs inside a PHP request. A request has a time limit ($cfg['ExecTimeLimit'], 300 seconds by default) and a memory limit, and the web server in front of it has its own. A dump that takes four minutes to import is fine. One that takes forty is not going to finish through a browser, whatever you do to it.
  • It can only do what your database user can do. phpMyAdmin is not a privileged back door. If the user attached to your database cannot create a trigger, an import containing a trigger will stop on that line no matter which options you tick.

phpMyAdmin is also specifically a MySQL-family tool. It does not manage PostgreSQL or MongoDB, and no amount of configuration makes it. If your database is Postgres, the equivalent job is pg_dump and pg_restore; if it is Mongo, it is mongodump and mongorestore. The rest of this post assumes the tool in front of you is phpMyAdmin.

Opening the database slot on a panel host#

On a panel-based host you do not install phpMyAdmin or know where it lives. The plan includes a number of database slots, and each slot is created from the panel's Databases tab. Creating one generates four things you will need again:

FieldWhat it is
HostThe address the database answers on, often not localhost
Database nameUsually prefixed, for example s14_shop
UsernameGenerated, and tied to that one database
PasswordGenerated, shown in the panel, rotatable

Those four values are what goes into wp-config.php, a .env file, or a connection string. Keep them out of your code and out of version control - environment variables and secrets explains where they should live instead.

On RE:NODE the same tab has an Open in phpMyAdmin button. It signs you in with a one-use token that expires in 60 seconds, so the link cannot be forwarded, bookmarked or reused: if you open it and wander off to make coffee, you come back to a login page and press the button again. Database slots are included on every line that has them - one on a game plan, two on app and web plans - and the credentials are per database rather than per account. The database hosting line is a different product: those are PostgreSQL and MongoDB servers with their own superuser, and phpMyAdmin has nothing to do with them.

Exporting: quick, custom, and the options that matter#

Select the database in the left-hand tree first, not a table, unless you genuinely want one table. Then Export. Two methods are offered.

Quick gives you a plain .sql file with sensible defaults. It is the right choice for a small database you are about to reimport somewhere similar.

Custom shows everything, and for anything you care about, use it. The options that change the outcome:

OptionSet it toWhy
FormatSQLCSV and JSON lose structure, keys and types
CompressiongzippedA text dump compresses about 5 to 10 times
Add DROP TABLEOn, for a restoreMakes the import idempotent
IF NOT EXISTSOff, for a restoreOtherwise existing tables are silently kept
AUTO_INCREMENTOnKeeps the next id after a restore
Enclose names with backquotesOnSurvives tables called order or group
Extended insertsOnFar fewer, far larger statements: much faster
Maximal length of created query50000 or lowerMust stay under the server's packet limit
Charset of the fileutf-8See the next section

Under "Object creation options" there are separate checkboxes for views, for routines (procedures, functions and events) and for triggers. They are not all on by default in every version, and the difference between a dump that restores a working application and one that restores a dead one is usually a missing stored procedure. Tick them, then open the dump and search for CREATE PROCEDURE and CREATE TRIGGER to confirm they are there.

"Extended inserts" is the single biggest performance lever. With it off you get one INSERT per row, which for a million-row table is a million round trips through the SQL parser. With it on you get one statement per batch:

sql
INSERT INTO `orders` (`id`, `total`, `created_at`) VALUES(1, 19.99, '2026-08-01 09:12:44'),(2, 42.50, '2026-08-01 09:31:02'),(3, 7.00,  '2026-08-01 10:04:19');

The batch size is governed by "Maximal length of created query". Leave it at the default unless an import fails with error 2006, which is the packet limit and is covered below.

Finally, choose "Save output to a file" rather than letting the SQL appear in the browser. A 200 MB dump rendered as a web page will take the tab down with it.

Character sets, or why your text turned into question marks#

This is the most common way an import "succeeds" and ruins the data. MySQL's character set called utf8 is not UTF-8. It is a three-byte subset, properly named utf8mb3, and it cannot store anything outside the basic multilingual plane: no emoji, no some of the rarer CJK characters, no mathematical symbols. The real thing is utf8mb4. Modern MySQL 8 defaults to utf8mb4; older servers and older MariaDB installations frequently default to latin1, and a database created years ago keeps whatever it was created with.

Check what you have before you export anything:

sql
SHOW VARIABLES LIKE 'character_set_%';SHOW CREATE DATABASE `shop`;SELECT table_name, table_collation FROM information_schema.tables  WHERE table_schema = 'shop';

A phpMyAdmin export writes its own declaration into the top of the file, which is what makes a dump portable:

sql
/*!40101 SET NAMES utf8mb4 */;SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";START TRANSACTION;SET time_zone = "+00:00";

On the Import tab there is a dropdown labelled "Character set of the file". It must match the bytes actually in the file, not what you wish they were. If the export said utf8mb4 and you import as latin1, every accented character becomes two characters of mojibake, and the import reports success. Nothing warns you. The damage is only visible when somebody opens the page and finds é where é used to be.

Three rules that avoid the whole category of problem:

  1. Export and import with the same character set, and prefer utf-8 on both ends.
  2. If the source database is latin1 and you want utf8mb4 on the target, convert after the import with ALTER TABLE ... CONVERT TO CHARACTER SET utf8mb4, not by lying to the importer.
  3. Never open a dump in a text editor that re-saves with a different encoding. Notepad on Windows has cost people entire databases this way.

Importing a dump#

Import, choose the file, confirm the format is SQL and the character set is right, press Go. The things on that page that are worth understanding:

  • The maximum size is printed on the page, as something like "Max: 2,048KiB". It comes from PHP's upload_max_filesize and post_max_size, whichever is smaller, and you usually cannot change it from inside phpMyAdmin.
  • Compressed files are accepted directly. A file named shop.sql.gz or shop.sql.zip is decompressed on the way in, and since the limit applies to the uploaded bytes, a gzipped dump raises your effective ceiling by roughly ten times. This is the easiest win available and most people miss it.
  • Partial import has two controls: "Allow the interruption of an import in case the script detects it is close to the PHP timeout limit", and "Skip this number of queries starting from the first one". Together they let you resume. If an import stops after 4,000 queries, tick the box, set the skip to 4,000, and run the same file again.
  • SQL compatibility mode should stay at NONE unless you are importing a dump from a much older server and you know which mode it needs.

Import into an empty database wherever you can. Importing on top of existing tables is how you get half-merged data that looks fine until a foreign key points at a row that is not there. Create a new database, import, test, then switch the application over.

If the dump has tables that reference each other and the order is wrong, the fix is to disable the checks around the import rather than to reorder the file by hand:

sql
SET FOREIGN_KEY_CHECKS = 0;-- paste or run the dump hereSET FOREIGN_KEY_CHECKS = 1;

Turn them back on in the same session, and afterwards run a query to prove nothing orphaned got through. Leaving foreign key checks off permanently is not a fix, it is a decision to find out later.

Getting a large file in when the upload limit is smaller#

You will hit this. In rough order of how much you should like them:

  1. Gzip the dump. Export with compression, or run gzip shop.sql locally. A 300 MB dump becomes 30 to 60 MB, which usually clears the limit on its own.
  2. Split the file. SQL dumps are line-oriented, so split works, provided you split on statement boundaries and keep the header with the first part. A dedicated dump splitter is safer than doing it by eye.
  3. Use the "web server upload directory" dropdown. If the host has configured $cfg['UploadDir'], you can put the file on the server with SFTP or the file manager and select it in phpMyAdmin instead of uploading it through the browser. This bypasses the upload limit entirely, though not the time limit. SFTP and the file manager covers getting the file up there.
  4. Skip and resume. Partial import, as above. Tedious but reliable.
  5. Use the command line if you have one. On a VDS with shell access the ceiling disappears:
bash
$ gunzip -c shop.sql.gz | mysql -h db.example.net -u shopuser -p shop

A shared web or game plan does not give you a shell, so options 1 to 4 are the real list there. If you find yourself doing this monthly, that is an argument for keeping the database on something you can reach from a terminal - see VDS or a game panel for the honest comparison.

Very large databases have a different answer again: do not move them with a logical dump at all if you can avoid it. Past roughly 5 GB the import time starts to be measured in hours, and the right approach is usually replication or a file-level copy, both of which need administrative access to both servers.

What an export does not contain#

A database export is a description of one database. Restoring it does not restore the things that live beside it:

  • Users and their grants. They are stored in the server's own system tables, which you are not exporting. After an import on a new host you create a new user and grant it rights on the new database. If the application's connection string still has the old username, it will fail to connect and you will blame the import.
  • Anything in other databases. Cross-database views and queries break silently until something calls them.
  • Server configuration. Packet sizes, timeouts, SQL mode, time zone tables. A query that worked on one server can fail on another because sql_mode differs, most often STRICT_TRANS_TABLES rejecting a zero date that the old server accepted.
  • Files. Uploaded images, a WordPress wp-content folder, user avatars. The database holds their paths, not their bytes. A site migration is always two jobs, and migrating WordPress to a new host walks through both.
  • The `DEFINER` accounts of views, triggers and routines in a usable form. The names come across, but they point at users that may not exist on the target, which produces error 1227.

An export is also not a backup strategy, because a backup you take by hand is a backup you will stop taking. Put it on a schedule, keep more than one generation, and restore one occasionally to prove it works. Database backups and restores is the longer argument, and testing a restore before you need it is the part people skip.

Errors and what each one means#

ErrorMessageCause and fix
1044Access denied for user to databaseThe dump has CREATE DATABASE or USE. Remove those lines and import into the database you already have
1045Access denied for userWrong password, or the user is restricted to a different host
1046No database selectedYou are at the server root. Click the database first, then Import
1062Duplicate entry for key PRIMARYImporting on top of existing rows. Import into an empty database
1064Syntax error nearA truncated file, a bad split, or a dump from a newer server version
1071Specified key was too longAn old server with a 767-byte index limit and utf8mb4 columns. Shorten the index or upgrade
1227Access denied, you need SUPER privilegesA DEFINER clause naming a user you are not. Edit the dump to remove the clauses
2006Server has gone awayOne statement exceeded max_allowed_packet, or the import timed out

Two of those deserve more than a table row.

Error 1227 and `DEFINER`. Views, triggers, procedures and events are exported with the account that created them baked into the statement, in the form DEFINER=old_user@localhost. On a new host that account does not exist and you are not allowed to invent it, so the statement is rejected. The fix is a search and replace on the dump before importing: delete every DEFINER= fragment and the user name that follows it, leaving the CREATE VIEW or CREATE TRIGGER statement intact. The objects are then created as you, which is what you want.

Error 2006 and the packet limit. max_allowed_packet caps the size of a single statement. An extended insert built from a table with large text or blob columns can exceed it. Re-export with "Maximal length of created query" set lower - 16000 is a safe value - and the same data arrives as more, smaller statements. The same error also appears when the connection simply timed out mid-import, which is a different problem with the same message.

A worked example: moving a site to a new host#

The order matters, because the goal is that no writes happen to the old database after you take the copy.

  1. Put the site into maintenance mode, or accept that anything written from now on will be lost.
  2. In phpMyAdmin on the old host: Export, Custom, SQL, gzipped, DROP TABLE on, views and routines ticked, save to a file. Check the file size is plausible - a 4 KB dump of a live shop means you exported the wrong thing.
  3. On the new host, create the database slot and note the host, name, user and password.
  4. Open phpMyAdmin from the panel, select the new database, Import, choose the .sql.gz file, character set utf-8, Go.
  5. Compare row counts on the biggest three tables, on both sides, with SELECT COUNT(*). This takes a minute and catches a truncated import immediately.
  6. Update the application's credentials to the new host, name, user and password. For WordPress that is four lines in wp-config.php.
  7. Copy the files across, then point DNS at the new address. DNS records explained covers which record to change; leave the old server running until it has propagated.
  8. Keep the dump file for a fortnight. It costs nothing and it is the only way back.

If the site stores absolute URLs in the database, as WordPress does, a straight import leaves it pointing at the old domain. Do not run a plain UPDATE ... REPLACE over the content: serialised PHP arrays store their own string lengths, and a naive replace corrupts them. Use a search-replace tool that understands serialisation, or WP-CLI's search-replace, which does.

FAQ#

Why does my import stop partway through with no error?

Almost always the PHP time limit. The request was killed while the import was still running, so the browser shows a truncated page or a blank one. Tick "Allow the interruption of an import", note how many queries completed, and rerun the file with that number in the skip box.

Can I export just one table?

Yes. Select the table in the left-hand tree before clicking Export, or select the database and choose which tables to include under Custom. Remember that a single table taken out of a set that uses foreign keys will not import into an empty database on its own.

Is a gzipped export safe to keep as a backup?

It is a valid logical copy of the database at the moment it was taken, and it will restore into any compatible server. What it is not is automatic, verified or stored anywhere but where you put it. Treat it as one copy of three, and check occasionally that it still opens.

The Import page says Max 2,048KiB and my file is 40 MB. Can I raise it?

Not from inside phpMyAdmin - it is a PHP setting on the web server. Compress the file first, use the server upload directory if the host offers one, or split the dump. On a machine where you control PHP, raising upload_max_filesize and post_max_size together does it.

Why do some characters look wrong after a perfectly successful import?

The character set of the file did not match what was in it. Restore the original dump into a fresh empty database with the correct setting rather than trying to repair the text in place, and see the character set section above for how to check what you have.

Do I need phpMyAdmin at all if my host gives me a database?

No. It is a convenience. Any client that speaks the protocol works, including desktop tools and the command line, and for large or repeated jobs those are better. phpMyAdmin earns its place for quick edits, a look at what is actually in a table, and a one-off export from a machine where you have nothing else installed.


Comments

Completely anonymous: no account, no email, no cookie. We store the name you type, the text and the time - nothing else. Links are limited and markup is not rendered.

0/2000