<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/">
	<channel>
		<title><![CDATA[AdminsForum - aaPanel Databases & phpMyAdmin Guides]]></title>
		<link>https://adminsforum.com/</link>
		<description><![CDATA[AdminsForum - https://adminsforum.com]]></description>
		<pubDate>Thu, 15 Oct 2026 07:04:52 +0000</pubDate>
		<generator>MyBB</generator>
		<item>
			<title><![CDATA[Fix Unknown Collation Error 1273 in aaPanel Imports]]></title>
			<link>https://adminsforum.com/Thread-guide-fix-unknown-collation-error-1273-in-aapanel-imports</link>
			<pubDate>Thu, 15 Oct 2026 14:56:37 +0800</pubDate>
			<dc:creator><![CDATA[<a href="https://adminsforum.com/member.php?action=profile&uid=2">DEV</a>]]></dc:creator>
			<guid isPermaLink="false">https://adminsforum.com/Thread-guide-fix-unknown-collation-error-1273-in-aapanel-imports</guid>
			<description><![CDATA[<span style="font-weight: bold;" class="mycode_b">“Unknown collation” error 1273 during an import means the target server does not recognize a collation name used by the SQL. Confirm the target version and available collations before editing the dump or changing server defaults.</span><br />
<br />
A collation defines comparison and sorting behavior. Choosing a recognized name can make a table definition run, but does not prove that sorting, equality and unique keys still match the source application's requirements.<br />
<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=334" target="_blank" title="">database-collation-20261015.jpg</a> (Size: 126.79 KB / Downloads: 3)
<!-- end: postbit_attachments_attachment --><br />
<span style="font-style: italic;" class="mycode_i">Original AdminsForum private lab results, formatted as a transcript rather than a screenshot.</span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">1. Save the original dump and exact error</span><br />
Keep an unchanged copy of the source export. Record the source database product/version, target product/version, failing statement or import position and exact collation name. Do not publish a full dump: it can contain account data, secrets and private content.<br />
<br />
An import can execute earlier statements before stopping. Do not repeatedly run an edited file into a partly populated live database. Rehearse recovery in an isolated destination and verify what already committed before planning any production action.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">2. Ask the target server what it supports</span><br />
From an authorized database session on the actual destination, run:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>SELECT VERSION();
SHOW COLLATION WHERE Collation = 'utf8mb4_0900_ai_ci';
SHOW COLLATION WHERE Charset = 'utf8mb4';</code></div></div>Replace the specific name with the one in your error. An empty result for that name is evidence of absence on that server. The broader listing helps identify supported choices; it does not establish their semantic equivalence.<br />
<br />
Do not infer support from “MySQL-compatible” branding alone. MariaDB versions differ, and newer versions can support names missing from older versions. A web-panel version is not the database-server version.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">3. Locate where the unsupported name is declared</span><br />
Review the failing schema statement in a protected local copy of the export. The name may appear at database, table or column level, or in another SQL expression. Identify each relevant declaration and its associated character set.<br />
<br />
Changing only the destination database default will not necessarily override explicit table or column declarations inside the dump. Conversely, replacing every matching word in a dump can alter places you did not intend, including data text. Prefer a controlled schema/export compatibility plan over a blind global replacement.<br />
<br />
If using aaPanel's installed database tools or phpMyAdmin, confirm you selected the isolated destination before any import. The import workflow itself is covered in the related guide; this tutorial investigates collation compatibility rather than repeating the upload steps.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">4. What our private lab actually tested</span><br />
The target was <span style="font-weight: bold;" class="mycode_b">MariaDB 10.11.10</span> in the aaPanel lab. We used one disposable InnoDB table in a separate test database.<br />
<ul class="mycode_list"><li>The target's collation lookup returned no row for <span style="font-weight: bold;" class="mycode_b">utf8mb4_0900_ai_ci</span>. Creating the test table with that explicit collation returned <span style="font-weight: bold;" class="mycode_b">1273: Unknown collation</span>.<br />
</li>
<li>The lookup confirmed <span style="font-weight: bold;" class="mycode_b">utf8mb4_unicode_ci</span> was available. A disposable table using that candidate and utf8mb4 was created successfully.<br />
</li>
<li>In the candidate table's unique text key, inserting <span style="font-weight: bold;" class="mycode_b">Cafe</span> and then <span style="font-weight: bold;" class="mycode_b">café</span> produced a duplicate-key error <span style="font-weight: bold;" class="mycode_b">1062</span> on the second value. That demonstrates equality behavior relevant to a unique key.<br />
</li>
<li>A separate string containing a four-byte character was stored, and its hexadecimal bytes were read back to verify that small example.<br />
</li>
</ul>
We did not run those comparisons on the source collation, which was unavailable on this server. The test therefore does not prove either equality or difference between the candidate and a real source database. It does not validate every language, sort order, trailing-space rule or application query.<br />
<br />
The disposable table was removed and the connection closed. No global database defaults or production tables changed. The normal HTTPS website returned 200 afterward.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">5. Choose a migration approach based on requirements</span><br />
Check whether the source application's export process supports the intended target server. A compatible target version or a supported export/schema strategy may be preferable to substituting collation names.<br />
<br />
If considering a different target collation, list the behavior the application needs: language-specific ordering, case and accent treatment, comparisons, joins and unique-key rules. Test representative real-world values in a protected staging environment with appropriate data handling.<br />
<br />
Do not assume utf8mb4_unicode_ci is the right answer merely because it worked in this small lab. It was a candidate used to demonstrate the decision process, not a universal recommendation. An upgrade also needs its own application compatibility, backup and rollback plan; do not upgrade a shared database service just to clear one import message.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">6. Keep character encoding and collation separate</span><br />
A compatible collation name must be considered alongside the character set and connection encoding. Removing four-byte character support to make a declaration parse can lose valid application data.<br />
<br />
Verify representative non-ASCII and four-byte characters through the application's actual connection and read-back path. The lab's one stored string was only a narrow check, not proof that an entire export was correctly encoded or converted.<br />
<br />
Also inspect column-level definitions after the staged import. A successful connection or a changed database default alone does not prove every text column uses the intended configuration.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">7. Rehearse the import and validate the data</span><br />
Use a fresh isolated target with the reviewed schema plan and keep the original dump unchanged. Confirm the schema creates, then load representative data and inspect errors and warnings. Investigate any new duplicate-key conflict; do not drop unique constraints to force completion.<br />
<br />
Compare expected table and row counts, selected values, relationships and application behavior. Exercise searches, sorting, equality checks and uniqueness-sensitive actions. Include values that distinguish the application's required comparison rules. Check that no rows were silently skipped.<br />
<br />
An import tool reporting completion is only one signal. The database must also preserve the application's intended data semantics. Our lab was not a full migration rehearsal and did not test a production cutover.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">8. Plan the production change and rollback separately</span><br />
Back up the destination and confirm a tested restore path before any real import or schema conversion. Record the reviewed changes and their scope. Schedule the migration around writes and application consistency needs, then verify the same checks after cutover.<br />
<br />
Do not overwrite or empty a live database as a troubleshooting shortcut. If the rehearsal shows incompatible behavior, stop the conversion plan and resolve that mismatch before touching the live target.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">For a support request</span><br />
Include both server products/versions, exact unsupported name, redacted failing schema and whether the destination is empty or partially imported. Describe the required comparison behavior without attaching private data dumps.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Related guides</span><br />
<a href="https://adminsforum.com/Thread-guide-import-a-sql-database-file-in-aapanel-step-by-step" target="_blank" rel="noopener" class="mycode_url">Import a SQL database file in aaPanel</a><br />
<a href="https://adminsforum.com/Thread-guide-fix-mariadb-duplicate-entry-error-1062-in-aapanel" target="_blank" rel="noopener" class="mycode_url">Investigate duplicate-key error 1062</a><br />
<a href="https://adminsforum.com/Thread-guide-back-up-and-restore-a-database-in-aapanel-free-edition" target="_blank" rel="noopener" class="mycode_url">Back up and restore a database</a><br />
<br />
<span style="font-weight: bold;" class="mycode_b">Technical references</span><br />
<a href="https://mariadb.com/docs/server/reference/data-types/string-data-types/character-sets/supported-character-sets-and-collations" target="_blank" rel="noopener" class="mycode_url">MariaDB supported character sets and collations</a><br />
<a href="https://mariadb.com/docs/server/reference/data-types/string-data-types/character-sets/setting-character-sets-and-collations" target="_blank" rel="noopener" class="mycode_url">Setting character sets and collations</a><br />
<a href="https://mariadb.com/docs/server/server-management/install-and-upgrade-mariadb/migrating-to-mariadb/moving-from-mysql/mysql-to-mariadb-compatibility-matrix" target="_blank" rel="noopener" class="mycode_url">MySQL-to-MariaDB compatibility considerations</a>]]></description>
			<content:encoded><![CDATA[<span style="font-weight: bold;" class="mycode_b">“Unknown collation” error 1273 during an import means the target server does not recognize a collation name used by the SQL. Confirm the target version and available collations before editing the dump or changing server defaults.</span><br />
<br />
A collation defines comparison and sorting behavior. Choosing a recognized name can make a table definition run, but does not prove that sorting, equality and unique keys still match the source application's requirements.<br />
<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=334" target="_blank" title="">database-collation-20261015.jpg</a> (Size: 126.79 KB / Downloads: 3)
<!-- end: postbit_attachments_attachment --><br />
<span style="font-style: italic;" class="mycode_i">Original AdminsForum private lab results, formatted as a transcript rather than a screenshot.</span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">1. Save the original dump and exact error</span><br />
Keep an unchanged copy of the source export. Record the source database product/version, target product/version, failing statement or import position and exact collation name. Do not publish a full dump: it can contain account data, secrets and private content.<br />
<br />
An import can execute earlier statements before stopping. Do not repeatedly run an edited file into a partly populated live database. Rehearse recovery in an isolated destination and verify what already committed before planning any production action.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">2. Ask the target server what it supports</span><br />
From an authorized database session on the actual destination, run:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>SELECT VERSION();
SHOW COLLATION WHERE Collation = 'utf8mb4_0900_ai_ci';
SHOW COLLATION WHERE Charset = 'utf8mb4';</code></div></div>Replace the specific name with the one in your error. An empty result for that name is evidence of absence on that server. The broader listing helps identify supported choices; it does not establish their semantic equivalence.<br />
<br />
Do not infer support from “MySQL-compatible” branding alone. MariaDB versions differ, and newer versions can support names missing from older versions. A web-panel version is not the database-server version.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">3. Locate where the unsupported name is declared</span><br />
Review the failing schema statement in a protected local copy of the export. The name may appear at database, table or column level, or in another SQL expression. Identify each relevant declaration and its associated character set.<br />
<br />
Changing only the destination database default will not necessarily override explicit table or column declarations inside the dump. Conversely, replacing every matching word in a dump can alter places you did not intend, including data text. Prefer a controlled schema/export compatibility plan over a blind global replacement.<br />
<br />
If using aaPanel's installed database tools or phpMyAdmin, confirm you selected the isolated destination before any import. The import workflow itself is covered in the related guide; this tutorial investigates collation compatibility rather than repeating the upload steps.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">4. What our private lab actually tested</span><br />
The target was <span style="font-weight: bold;" class="mycode_b">MariaDB 10.11.10</span> in the aaPanel lab. We used one disposable InnoDB table in a separate test database.<br />
<ul class="mycode_list"><li>The target's collation lookup returned no row for <span style="font-weight: bold;" class="mycode_b">utf8mb4_0900_ai_ci</span>. Creating the test table with that explicit collation returned <span style="font-weight: bold;" class="mycode_b">1273: Unknown collation</span>.<br />
</li>
<li>The lookup confirmed <span style="font-weight: bold;" class="mycode_b">utf8mb4_unicode_ci</span> was available. A disposable table using that candidate and utf8mb4 was created successfully.<br />
</li>
<li>In the candidate table's unique text key, inserting <span style="font-weight: bold;" class="mycode_b">Cafe</span> and then <span style="font-weight: bold;" class="mycode_b">café</span> produced a duplicate-key error <span style="font-weight: bold;" class="mycode_b">1062</span> on the second value. That demonstrates equality behavior relevant to a unique key.<br />
</li>
<li>A separate string containing a four-byte character was stored, and its hexadecimal bytes were read back to verify that small example.<br />
</li>
</ul>
We did not run those comparisons on the source collation, which was unavailable on this server. The test therefore does not prove either equality or difference between the candidate and a real source database. It does not validate every language, sort order, trailing-space rule or application query.<br />
<br />
The disposable table was removed and the connection closed. No global database defaults or production tables changed. The normal HTTPS website returned 200 afterward.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">5. Choose a migration approach based on requirements</span><br />
Check whether the source application's export process supports the intended target server. A compatible target version or a supported export/schema strategy may be preferable to substituting collation names.<br />
<br />
If considering a different target collation, list the behavior the application needs: language-specific ordering, case and accent treatment, comparisons, joins and unique-key rules. Test representative real-world values in a protected staging environment with appropriate data handling.<br />
<br />
Do not assume utf8mb4_unicode_ci is the right answer merely because it worked in this small lab. It was a candidate used to demonstrate the decision process, not a universal recommendation. An upgrade also needs its own application compatibility, backup and rollback plan; do not upgrade a shared database service just to clear one import message.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">6. Keep character encoding and collation separate</span><br />
A compatible collation name must be considered alongside the character set and connection encoding. Removing four-byte character support to make a declaration parse can lose valid application data.<br />
<br />
Verify representative non-ASCII and four-byte characters through the application's actual connection and read-back path. The lab's one stored string was only a narrow check, not proof that an entire export was correctly encoded or converted.<br />
<br />
Also inspect column-level definitions after the staged import. A successful connection or a changed database default alone does not prove every text column uses the intended configuration.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">7. Rehearse the import and validate the data</span><br />
Use a fresh isolated target with the reviewed schema plan and keep the original dump unchanged. Confirm the schema creates, then load representative data and inspect errors and warnings. Investigate any new duplicate-key conflict; do not drop unique constraints to force completion.<br />
<br />
Compare expected table and row counts, selected values, relationships and application behavior. Exercise searches, sorting, equality checks and uniqueness-sensitive actions. Include values that distinguish the application's required comparison rules. Check that no rows were silently skipped.<br />
<br />
An import tool reporting completion is only one signal. The database must also preserve the application's intended data semantics. Our lab was not a full migration rehearsal and did not test a production cutover.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">8. Plan the production change and rollback separately</span><br />
Back up the destination and confirm a tested restore path before any real import or schema conversion. Record the reviewed changes and their scope. Schedule the migration around writes and application consistency needs, then verify the same checks after cutover.<br />
<br />
Do not overwrite or empty a live database as a troubleshooting shortcut. If the rehearsal shows incompatible behavior, stop the conversion plan and resolve that mismatch before touching the live target.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">For a support request</span><br />
Include both server products/versions, exact unsupported name, redacted failing schema and whether the destination is empty or partially imported. Describe the required comparison behavior without attaching private data dumps.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Related guides</span><br />
<a href="https://adminsforum.com/Thread-guide-import-a-sql-database-file-in-aapanel-step-by-step" target="_blank" rel="noopener" class="mycode_url">Import a SQL database file in aaPanel</a><br />
<a href="https://adminsforum.com/Thread-guide-fix-mariadb-duplicate-entry-error-1062-in-aapanel" target="_blank" rel="noopener" class="mycode_url">Investigate duplicate-key error 1062</a><br />
<a href="https://adminsforum.com/Thread-guide-back-up-and-restore-a-database-in-aapanel-free-edition" target="_blank" rel="noopener" class="mycode_url">Back up and restore a database</a><br />
<br />
<span style="font-weight: bold;" class="mycode_b">Technical references</span><br />
<a href="https://mariadb.com/docs/server/reference/data-types/string-data-types/character-sets/supported-character-sets-and-collations" target="_blank" rel="noopener" class="mycode_url">MariaDB supported character sets and collations</a><br />
<a href="https://mariadb.com/docs/server/reference/data-types/string-data-types/character-sets/setting-character-sets-and-collations" target="_blank" rel="noopener" class="mycode_url">Setting character sets and collations</a><br />
<a href="https://mariadb.com/docs/server/server-management/install-and-upgrade-mariadb/migrating-to-mariadb/moving-from-mysql/mysql-to-mariadb-compatibility-matrix" target="_blank" rel="noopener" class="mycode_url">MySQL-to-MariaDB compatibility considerations</a>]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[Fix MariaDB Foreign Key Errors 1451 and 1452 in aaPanel]]></title>
			<link>https://adminsforum.com/Thread-guide-fix-mariadb-foreign-key-errors-1451-and-1452-in-aapanel</link>
			<pubDate>Thu, 15 Oct 2026 14:33:22 +0800</pubDate>
			<dc:creator><![CDATA[<a href="https://adminsforum.com/member.php?action=profile&uid=2">DEV</a>]]></dc:creator>
			<guid isPermaLink="false">https://adminsforum.com/Thread-guide-fix-mariadb-foreign-key-errors-1451-and-1452-in-aapanel</guid>
			<description><![CDATA[<span style="font-weight: bold;" class="mycode_b">MariaDB foreign-key errors protect relationships between records. Error 1452 usually concerns a child that cannot reference the required parent; error 1451 can block a parent change when dependent rows still exist. Read the actual constraint before changing data.</span><br />
<br />
This guide demonstrates both errors in disposable InnoDB tables in a separate aaPanel lab database. We kept checks enabled and verified a valid parent-before-child insertion. No live application relationship or cascade policy was changed.<br />
<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=333" target="_blank" title="">database-foreignkey-20261015.jpg</a> (Size: 125.72 KB / Downloads: 3)
<!-- end: postbit_attachments_attachment --><br />
<span style="font-style: italic;" class="mycode_i">Original AdminsForum lab evidence, formatted as a transcript rather than a screenshot.</span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">1. Capture the exact error and operation</span><br />
Record the database error code, time, application action or import step, table and named constraint. If the website shows only a generic failure, inspect its private application log and correlate the site logs through aaPanel's <span style="font-weight: bold;" class="mycode_b">Website → PHP Project → Log</span> workflow. Labels may vary.<br />
<br />
The two error meanings are:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>1452: Cannot add or update a child row:
a foreign key constraint fails

1451: Cannot delete or update a parent row:
a foreign key constraint fails</code></div></div>A child stores the reference; a parent supplies the referenced key. For example, a lab task can refer to a lab project. This relationship is a database rule, not a missing PHP extension or a web-server timeout.<br />
<br />
Redact identifiers and private values before sharing messages. Do not publish a complete customer database dump to illustrate an error.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">2. Identify the actual relationship</span><br />
In an authorized database session, inspect the affected table's definition:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>SHOW CREATE TABLE your_child_table;</code></div></div>Use the correct database and real table name. Find the named FOREIGN KEY, child columns, referenced table and columns, and ON DELETE/ON UPDATE actions. Composite relationships need every relevant column checked.<br />
<br />
Review the intended parent and dependent rows with scoped read-only queries. Use parameterized application queries for untrusted input. Do not assume that two IDs with the same number represent the same entity after a migration or import.<br />
<br />
A constraint-creation failure is a different investigation from these tested data-write errors. If the table or foreign key cannot be created, collect that error and the full relevant definitions instead of applying a data-insert fix.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">3. Diagnose a 1452 child-write failure</span><br />
Check whether the referenced parent exists in the intended database and whether the application supplied the right reference. An import can load child data before its parents, omit a required parent set or map old IDs incorrectly.<br />
<br />
For genuinely new related records, create the legitimate parent through the supported application workflow before its child. Do not invent a dummy customer or project merely to satisfy a database check. A wrong child reference may need an input correction, not a new parent.<br />
<br />
Also review the application's transaction boundaries and error handling. A parent created in a different uncommitted or failed operation may not be available as the caller expects. This guide's lab used simple committed statements, not a concurrent import or cross-service workflow.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">4. Diagnose a 1451 parent-change failure</span><br />
Identify which child records still reference the parent and what the existing relationship policy requires. Under a restrictive policy, blocking the parent deletion can be the correct result.<br />
<br />
Decide through the application's data-lifecycle rules whether the parent should be retained, archived or handled by an authorized workflow for related records. Do not delete child rows just to make a parent-delete command succeed. Those rows may be business history.<br />
<br />
Cascade and set-null policies are schema-design decisions with their own conditions and consequences. Do not add ON DELETE CASCADE as a generic repair. Our test deliberately used RESTRICT and did not validate an application's deletion policy.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">5. What the private aaPanel lab demonstrated</span><br />
On <span style="font-weight: bold;" class="mycode_b">MariaDB 10.11.10</span>, we created one disposable parent table and one child table using InnoDB. The child required a parent ID and the named foreign key used restrictive update and delete actions.<br />
<ul class="mycode_list"><li>Parent 1 and child 1 → parent 1 were inserted successfully.<br />
</li>
<li>A new child pointing to nonexistent parent <span style="font-weight: bold;" class="mycode_b">999</span> returned <span style="font-weight: bold;" class="mycode_b">1452</span>.<br />
</li>
<li>Deleting parent 1 while its child existed returned <span style="font-weight: bold;" class="mycode_b">1451</span>. A check confirmed the original parent remained.<br />
</li>
<li>We then added an intentionally valid new parent 2, followed by child 2 → parent 2. Both succeeded.<br />
</li>
<li>The final child relationships were <span style="font-weight: bold;" class="mycode_b">1 → 1</span> and <span style="font-weight: bold;" class="mycode_b">2 → 2</span>. The orphan check returned <span style="font-weight: bold;" class="mycode_b">zero</span>, with the constraint retained and foreign-key checks still enabled.<br />
</li>
</ul>
These are synthetic relationships, not a repair of customer data. The two disposable tables were removed in dependency order after testing and the connection closed. No global database setting changed, and the normal HTTPS website returned 200 afterward.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">6. Do not bypass integrity to hide the error</span><br />
Disabling checks or dropping the relationship can let a write proceed without establishing a valid data model. That does not prove the application is repaired. Keep the constraint while investigating the input, import sequence and intended record lifecycle.<br />
<br />
Similarly, blindly ignoring an error can leave an expected child absent. Check actual row counts and relationships rather than only whether a tool reports completion. If a specialized restore procedure requires different handling, rehearse and validate that separate procedure in an isolated destination first.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">7. Verify relationships with a scoped orphan check</span><br />
For a simple non-null single-column relationship, an illustrative read-only check is:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>SELECT COUNT(*) AS orphan_count
FROM your_child_table AS ch
LEFT JOIN your_parent_table AS pa ON pa.id = ch.parent_id
WHERE pa.id IS NULL;</code></div></div>Replace the names and join with the actual relationship. This example assumes the child reference must be non-null; optional null relationships and composite keys need an adapted query. Do not treat a generic join as a complete database integrity audit.<br />
<br />
Run bounded checks on the intended data scope, with an administrator reviewing cost on large tables. Do not paste all matching customer rows publicly.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">8. Apply a justified correction and test the application</span><br />
Back up affected data before corrective writes. Use supported application workflows and verify that the intended identities and permissions match. For an import, confirm the source-to-target key mapping and parent/child order in a staging rehearsal.<br />
<br />
Afterward inspect the intended parent and child records, verify no expected rows were silently skipped and confirm the constraint remains. Test the original safe application action and check for new matching errors. One successful insert does not validate every relationship in a restore.<br />
<br />
Keep a rollback plan and remove disposable test fixtures. Do not drop live tables or wipe related records as a troubleshooting shortcut.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">For a support request</span><br />
Share the version, error code, named relationship, redacted definitions, operation type and recent import/deployment changes. Explain the intended parent/child outcome without sharing credentials or private records.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Related guides</span><br />
<a href="https://adminsforum.com/Thread-guide-fix-mariadb-duplicate-entry-error-1062-in-aapanel" target="_blank" rel="noopener" class="mycode_url">Investigate duplicate-key error 1062</a><br />
<a href="https://adminsforum.com/Thread-guide-import-a-sql-database-file-in-aapanel-step-by-step" target="_blank" rel="noopener" class="mycode_url">Import a database file in aaPanel</a><br />
<a href="https://adminsforum.com/Thread-guide-back-up-and-restore-a-database-in-aapanel-free-edition" target="_blank" rel="noopener" class="mycode_url">Back up and restore a database</a><br />
<br />
<span style="font-weight: bold;" class="mycode_b">Technical references</span><br />
<a href="https://mariadb.com/docs/server/architecture/server-constraints/foreign-key-constraints" target="_blank" rel="noopener" class="mycode_url">MariaDB foreign-key constraints</a><br />
<a href="https://mariadb.com/docs/server/ha-and-performance/optimization-and-tuning/optimization-and-indexes/foreign-keys" target="_blank" rel="noopener" class="mycode_url">Foreign-key relationship rules</a><br />
<a href="https://mariadb.com/docs/server/reference/error-codes/mariadb-error-codes-1400-to-1499/e1451" target="_blank" rel="noopener" class="mycode_url">MariaDB error 1451</a><br />
<a href="https://mariadb.com/docs/server/reference/error-codes/mariadb-error-codes-1400-to-1499/e1452" target="_blank" rel="noopener" class="mycode_url">MariaDB error 1452</a>]]></description>
			<content:encoded><![CDATA[<span style="font-weight: bold;" class="mycode_b">MariaDB foreign-key errors protect relationships between records. Error 1452 usually concerns a child that cannot reference the required parent; error 1451 can block a parent change when dependent rows still exist. Read the actual constraint before changing data.</span><br />
<br />
This guide demonstrates both errors in disposable InnoDB tables in a separate aaPanel lab database. We kept checks enabled and verified a valid parent-before-child insertion. No live application relationship or cascade policy was changed.<br />
<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=333" target="_blank" title="">database-foreignkey-20261015.jpg</a> (Size: 125.72 KB / Downloads: 3)
<!-- end: postbit_attachments_attachment --><br />
<span style="font-style: italic;" class="mycode_i">Original AdminsForum lab evidence, formatted as a transcript rather than a screenshot.</span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">1. Capture the exact error and operation</span><br />
Record the database error code, time, application action or import step, table and named constraint. If the website shows only a generic failure, inspect its private application log and correlate the site logs through aaPanel's <span style="font-weight: bold;" class="mycode_b">Website → PHP Project → Log</span> workflow. Labels may vary.<br />
<br />
The two error meanings are:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>1452: Cannot add or update a child row:
a foreign key constraint fails

1451: Cannot delete or update a parent row:
a foreign key constraint fails</code></div></div>A child stores the reference; a parent supplies the referenced key. For example, a lab task can refer to a lab project. This relationship is a database rule, not a missing PHP extension or a web-server timeout.<br />
<br />
Redact identifiers and private values before sharing messages. Do not publish a complete customer database dump to illustrate an error.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">2. Identify the actual relationship</span><br />
In an authorized database session, inspect the affected table's definition:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>SHOW CREATE TABLE your_child_table;</code></div></div>Use the correct database and real table name. Find the named FOREIGN KEY, child columns, referenced table and columns, and ON DELETE/ON UPDATE actions. Composite relationships need every relevant column checked.<br />
<br />
Review the intended parent and dependent rows with scoped read-only queries. Use parameterized application queries for untrusted input. Do not assume that two IDs with the same number represent the same entity after a migration or import.<br />
<br />
A constraint-creation failure is a different investigation from these tested data-write errors. If the table or foreign key cannot be created, collect that error and the full relevant definitions instead of applying a data-insert fix.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">3. Diagnose a 1452 child-write failure</span><br />
Check whether the referenced parent exists in the intended database and whether the application supplied the right reference. An import can load child data before its parents, omit a required parent set or map old IDs incorrectly.<br />
<br />
For genuinely new related records, create the legitimate parent through the supported application workflow before its child. Do not invent a dummy customer or project merely to satisfy a database check. A wrong child reference may need an input correction, not a new parent.<br />
<br />
Also review the application's transaction boundaries and error handling. A parent created in a different uncommitted or failed operation may not be available as the caller expects. This guide's lab used simple committed statements, not a concurrent import or cross-service workflow.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">4. Diagnose a 1451 parent-change failure</span><br />
Identify which child records still reference the parent and what the existing relationship policy requires. Under a restrictive policy, blocking the parent deletion can be the correct result.<br />
<br />
Decide through the application's data-lifecycle rules whether the parent should be retained, archived or handled by an authorized workflow for related records. Do not delete child rows just to make a parent-delete command succeed. Those rows may be business history.<br />
<br />
Cascade and set-null policies are schema-design decisions with their own conditions and consequences. Do not add ON DELETE CASCADE as a generic repair. Our test deliberately used RESTRICT and did not validate an application's deletion policy.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">5. What the private aaPanel lab demonstrated</span><br />
On <span style="font-weight: bold;" class="mycode_b">MariaDB 10.11.10</span>, we created one disposable parent table and one child table using InnoDB. The child required a parent ID and the named foreign key used restrictive update and delete actions.<br />
<ul class="mycode_list"><li>Parent 1 and child 1 → parent 1 were inserted successfully.<br />
</li>
<li>A new child pointing to nonexistent parent <span style="font-weight: bold;" class="mycode_b">999</span> returned <span style="font-weight: bold;" class="mycode_b">1452</span>.<br />
</li>
<li>Deleting parent 1 while its child existed returned <span style="font-weight: bold;" class="mycode_b">1451</span>. A check confirmed the original parent remained.<br />
</li>
<li>We then added an intentionally valid new parent 2, followed by child 2 → parent 2. Both succeeded.<br />
</li>
<li>The final child relationships were <span style="font-weight: bold;" class="mycode_b">1 → 1</span> and <span style="font-weight: bold;" class="mycode_b">2 → 2</span>. The orphan check returned <span style="font-weight: bold;" class="mycode_b">zero</span>, with the constraint retained and foreign-key checks still enabled.<br />
</li>
</ul>
These are synthetic relationships, not a repair of customer data. The two disposable tables were removed in dependency order after testing and the connection closed. No global database setting changed, and the normal HTTPS website returned 200 afterward.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">6. Do not bypass integrity to hide the error</span><br />
Disabling checks or dropping the relationship can let a write proceed without establishing a valid data model. That does not prove the application is repaired. Keep the constraint while investigating the input, import sequence and intended record lifecycle.<br />
<br />
Similarly, blindly ignoring an error can leave an expected child absent. Check actual row counts and relationships rather than only whether a tool reports completion. If a specialized restore procedure requires different handling, rehearse and validate that separate procedure in an isolated destination first.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">7. Verify relationships with a scoped orphan check</span><br />
For a simple non-null single-column relationship, an illustrative read-only check is:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>SELECT COUNT(*) AS orphan_count
FROM your_child_table AS ch
LEFT JOIN your_parent_table AS pa ON pa.id = ch.parent_id
WHERE pa.id IS NULL;</code></div></div>Replace the names and join with the actual relationship. This example assumes the child reference must be non-null; optional null relationships and composite keys need an adapted query. Do not treat a generic join as a complete database integrity audit.<br />
<br />
Run bounded checks on the intended data scope, with an administrator reviewing cost on large tables. Do not paste all matching customer rows publicly.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">8. Apply a justified correction and test the application</span><br />
Back up affected data before corrective writes. Use supported application workflows and verify that the intended identities and permissions match. For an import, confirm the source-to-target key mapping and parent/child order in a staging rehearsal.<br />
<br />
Afterward inspect the intended parent and child records, verify no expected rows were silently skipped and confirm the constraint remains. Test the original safe application action and check for new matching errors. One successful insert does not validate every relationship in a restore.<br />
<br />
Keep a rollback plan and remove disposable test fixtures. Do not drop live tables or wipe related records as a troubleshooting shortcut.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">For a support request</span><br />
Share the version, error code, named relationship, redacted definitions, operation type and recent import/deployment changes. Explain the intended parent/child outcome without sharing credentials or private records.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Related guides</span><br />
<a href="https://adminsforum.com/Thread-guide-fix-mariadb-duplicate-entry-error-1062-in-aapanel" target="_blank" rel="noopener" class="mycode_url">Investigate duplicate-key error 1062</a><br />
<a href="https://adminsforum.com/Thread-guide-import-a-sql-database-file-in-aapanel-step-by-step" target="_blank" rel="noopener" class="mycode_url">Import a database file in aaPanel</a><br />
<a href="https://adminsforum.com/Thread-guide-back-up-and-restore-a-database-in-aapanel-free-edition" target="_blank" rel="noopener" class="mycode_url">Back up and restore a database</a><br />
<br />
<span style="font-weight: bold;" class="mycode_b">Technical references</span><br />
<a href="https://mariadb.com/docs/server/architecture/server-constraints/foreign-key-constraints" target="_blank" rel="noopener" class="mycode_url">MariaDB foreign-key constraints</a><br />
<a href="https://mariadb.com/docs/server/ha-and-performance/optimization-and-tuning/optimization-and-indexes/foreign-keys" target="_blank" rel="noopener" class="mycode_url">Foreign-key relationship rules</a><br />
<a href="https://mariadb.com/docs/server/reference/error-codes/mariadb-error-codes-1400-to-1499/e1451" target="_blank" rel="noopener" class="mycode_url">MariaDB error 1451</a><br />
<a href="https://mariadb.com/docs/server/reference/error-codes/mariadb-error-codes-1400-to-1499/e1452" target="_blank" rel="noopener" class="mycode_url">MariaDB error 1452</a>]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[Fix MariaDB Duplicate Entry Error 1062 in aaPanel]]></title>
			<link>https://adminsforum.com/Thread-guide-fix-mariadb-duplicate-entry-error-1062-in-aapanel</link>
			<pubDate>Thu, 15 Oct 2026 14:12:05 +0800</pubDate>
			<dc:creator><![CDATA[<a href="https://adminsforum.com/member.php?action=profile&uid=2">DEV</a>]]></dc:creator>
			<guid isPermaLink="false">https://adminsforum.com/Thread-guide-fix-mariadb-duplicate-entry-error-1062-in-aapanel</guid>
			<description><![CDATA[<span style="font-weight: bold;" class="mycode_b">MariaDB error 1062 means an operation would violate a primary or unique key. Identify the key and intended record before changing the SQL: ignoring the error can leave the new data unsaved, while replacing a record can change existing data.</span><br />
<br />
This guide uses a disposable InnoDB table in a separate aaPanel lab database. It demonstrates duplicate rejection, INSERT IGNORE warnings and a corrected distinct record while retaining the unique constraint. No live application data was edited.<br />
<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=332" target="_blank" title="">database-duplicate-20261015.jpg</a> (Size: 123.29 KB / Downloads: 3)
<!-- end: postbit_attachments_attachment --><br />
<span style="font-style: italic;" class="mycode_i">Original AdminsForum lab results, formatted as a transcript rather than a screenshot.</span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">1. Capture the exact error and operation</span><br />
Record the time, application action or import step, table and key name from the error. A browser may show only a generic failure, so inspect the application's private logs and correlate the website error log in aaPanel.<br />
<br />
Under <span style="font-weight: bold;" class="mycode_b">Website → PHP Project</span>, find the site and open its <span style="font-weight: bold;" class="mycode_b">Log</span> control. Panel labels vary. Redact user values, email addresses and customer identifiers before sharing an error; the duplicate value can appear directly in the message.<br />
<br />
Our harmless lab example was:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>1062 / SQLSTATE 23000
Duplicate entry 'AF-LAB-001' for key 'uq_reference'</code></div></div>The named key was a unique reference index in our test, not necessarily the primary key. Do not assume every 1062 involves an auto-increment ID.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">2. Identify the columns protected by the named key</span><br />
In an authorized database session, inspect the affected table's structure or run a scoped read-only check:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>SHOW INDEX FROM your_table;</code></div></div>Replace your_table with the actual intended table in the correct database. Find the reported key name and its column sequence. A unique key can cover more than one column; the required uniqueness may be a combination rather than one field by itself.<br />
<br />
Then inspect only the relevant existing record using an appropriately parameterized query in the application or a careful read-only lookup in the administration tool. Do not paste untrusted values directly into SQL. Keep sensitive row contents private.<br />
<br />
A key conflict tells you the database rejected that value combination. It does not tell you whether the new input is wrong, the operation was repeated or an existing record should be updated.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">3. Decide what the operation was supposed to do</span><ul class="mycode_list"><li><span style="font-weight: bold;" class="mycode_b">Create a genuinely new record:</span> verify the source supplied the right unique identifier. Correct invalid input through the supported application workflow.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Repeat the same logical request:</span> inspect idempotency handling and the existing outcome. Repeating a request should not accidentally create a second order or account.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Update an existing record:</span> verify identity, authorization and intended changes before using the application's supported update path.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Import or restore data:</span> determine whether the target already contains earlier imported rows and what the source's merge policy is. Test the complete restore plan in an isolated destination.<br />
</li>
</ul>
Do not invent a new business identifier just to suppress an error. The lab's second identifier was deliberately a separate synthetic record; that does not make renaming a real customer's reference a valid repair.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">4. What our private test demonstrated</span><br />
We used <span style="font-weight: bold;" class="mycode_b">MariaDB 10.11.10</span> and a disposable two-column data example with an auto-increment primary key and an additional unique reference index. Initially AF-LAB-001 had value 10.<br />
<ul class="mycode_list"><li>A normal INSERT of AF-LAB-001 with value 20 returned <span style="font-weight: bold;" class="mycode_b">1062</span>. A read-back confirmed the existing value remained <span style="font-weight: bold;" class="mycode_b">10</span>.<br />
</li>
<li>The same duplicate with <span style="font-weight: bold;" class="mycode_b">INSERT IGNORE</span> reported <span style="font-weight: bold;" class="mycode_b">zero affected rows</span> and warning <span style="font-weight: bold;" class="mycode_b">1062</span>. A read-back again showed only the existing value 10: the proposed value 20 was not saved.<br />
</li>
<li>An intentionally distinct AF-LAB-002 record with value 20 inserted successfully. The final reference/value pairs were <span style="font-weight: bold;" class="mycode_b">AF-LAB-001 → 10</span> and <span style="font-weight: bold;" class="mycode_b">AF-LAB-002 → 20</span>.<br />
</li>
</ul>
The unique index remained in place throughout. These were single-row, autocommit statements against a private fixture, not a test of a real import, concurrent application requests or multi-statement rollback handling. The disposable table was removed and its connection closed afterward. No global settings changed, and the normal HTTPS website returned 200.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">5. Understand why common shortcuts change behavior</span><ul class="mycode_list"><li><span style="font-weight: bold;" class="mycode_b">INSERT IGNORE:</span> our test showed that a duplicate can become a warning while the row is not inserted. Review affected rows, warnings and final data; a command completing without an error is not proof all input was saved.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">ON DUPLICATE KEY UPDATE:</span> this intentionally updates on a key conflict. That can be appropriate only when its identity and update semantics match the application. It is not a harmless switch for any failed import.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">REPLACE:</span> this has replacement behavior involving deletion and insertion of conflicting rows. Do not treat it as a generic in-place update; review relationships, triggers and application consequences first.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Dropping uniqueness:</span> removing an intended unique index can permit invalid duplicates. Keep the integrity rule unless an independently reviewed schema-design change actually requires something different.<br />
</li>
</ul>
Only the ordinary INSERT and INSERT IGNORE paths were tested here. The other options are design considerations, not verified repairs for your application.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">6. Check repeated imports and concurrent requests</span><br />
For an import, record where it stopped and whether earlier statements committed. Re-running a partially applied file can encounter records already present. Do not empty a live database or delete the conflicting row without a validated restore or merge plan and backup.<br />
<br />
For an application, two requests can race even when each first checks whether a value exists. Retain the database constraint and handle the conflict according to the application's intended operation. An existence check alone is not a concurrency guarantee.<br />
<br />
If the conflict is specifically on PRIMARY, inspect how that identifier was supplied and the deployment/import history. Do not reset auto-increment values or renumber related records merely because the error mentions a duplicate.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">7. Apply one justified correction and read the data back</span><br />
Back up affected data and configuration before any real corrective write. Use the application's supported identity and authorization checks. If a restore is intended, rehearse it in an isolated database and verify counts, relationships and representative records.<br />
<br />
After the correction, check the actual row values and expected outcome as well as the SQL result. Inspect warnings in the same relevant session where appropriate. Confirm the unique key is retained and unrelated data is unchanged.<br />
<br />
Our lab used a distinct synthetic record because it represented a new item. A real repeated request may instead need to return the existing result, and a real update may need a specifically authorized change. Choose the behavior from the business operation, not the easiest way to silence 1062.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">For a support request</span><br />
Include the database version, key name, operation type, timestamp, whether the target already held data and a redacted error. Do not share passwords, complete SQL dumps or customer records.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Related guides</span><br />
<a href="https://adminsforum.com/Thread-guide-import-a-sql-database-file-in-aapanel-step-by-step" target="_blank" rel="noopener" class="mycode_url">Import a SQL database file in aaPanel</a><br />
<a href="https://adminsforum.com/Thread-guide-back-up-and-restore-a-database-in-aapanel-free-edition" target="_blank" rel="noopener" class="mycode_url">Back up and restore a database</a><br />
<a href="https://adminsforum.com/Thread-guide-tune-mariadb-queries-in-aapanel-with-explain-and-index-tests" target="_blank" rel="noopener" class="mycode_url">Review query plans and indexes</a><br />
<br />
<span style="font-weight: bold;" class="mycode_b">Technical references</span><br />
<a href="https://mariadb.com/docs/server/reference/error-codes/mariadb-error-codes-1000-to-1099/e1062" target="_blank" rel="noopener" class="mycode_url">MariaDB error 1062</a><br />
<a href="https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/inserting-loading-data/insert-ignore" target="_blank" rel="noopener" class="mycode_url">INSERT IGNORE behavior</a><br />
<a href="https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/inserting-loading-data/insert-on-duplicate-key-update" target="_blank" rel="noopener" class="mycode_url">ON DUPLICATE KEY UPDATE behavior</a><br />
<a href="https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/changing-deleting-data/replace" target="_blank" rel="noopener" class="mycode_url">REPLACE semantics</a>]]></description>
			<content:encoded><![CDATA[<span style="font-weight: bold;" class="mycode_b">MariaDB error 1062 means an operation would violate a primary or unique key. Identify the key and intended record before changing the SQL: ignoring the error can leave the new data unsaved, while replacing a record can change existing data.</span><br />
<br />
This guide uses a disposable InnoDB table in a separate aaPanel lab database. It demonstrates duplicate rejection, INSERT IGNORE warnings and a corrected distinct record while retaining the unique constraint. No live application data was edited.<br />
<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=332" target="_blank" title="">database-duplicate-20261015.jpg</a> (Size: 123.29 KB / Downloads: 3)
<!-- end: postbit_attachments_attachment --><br />
<span style="font-style: italic;" class="mycode_i">Original AdminsForum lab results, formatted as a transcript rather than a screenshot.</span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">1. Capture the exact error and operation</span><br />
Record the time, application action or import step, table and key name from the error. A browser may show only a generic failure, so inspect the application's private logs and correlate the website error log in aaPanel.<br />
<br />
Under <span style="font-weight: bold;" class="mycode_b">Website → PHP Project</span>, find the site and open its <span style="font-weight: bold;" class="mycode_b">Log</span> control. Panel labels vary. Redact user values, email addresses and customer identifiers before sharing an error; the duplicate value can appear directly in the message.<br />
<br />
Our harmless lab example was:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>1062 / SQLSTATE 23000
Duplicate entry 'AF-LAB-001' for key 'uq_reference'</code></div></div>The named key was a unique reference index in our test, not necessarily the primary key. Do not assume every 1062 involves an auto-increment ID.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">2. Identify the columns protected by the named key</span><br />
In an authorized database session, inspect the affected table's structure or run a scoped read-only check:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>SHOW INDEX FROM your_table;</code></div></div>Replace your_table with the actual intended table in the correct database. Find the reported key name and its column sequence. A unique key can cover more than one column; the required uniqueness may be a combination rather than one field by itself.<br />
<br />
Then inspect only the relevant existing record using an appropriately parameterized query in the application or a careful read-only lookup in the administration tool. Do not paste untrusted values directly into SQL. Keep sensitive row contents private.<br />
<br />
A key conflict tells you the database rejected that value combination. It does not tell you whether the new input is wrong, the operation was repeated or an existing record should be updated.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">3. Decide what the operation was supposed to do</span><ul class="mycode_list"><li><span style="font-weight: bold;" class="mycode_b">Create a genuinely new record:</span> verify the source supplied the right unique identifier. Correct invalid input through the supported application workflow.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Repeat the same logical request:</span> inspect idempotency handling and the existing outcome. Repeating a request should not accidentally create a second order or account.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Update an existing record:</span> verify identity, authorization and intended changes before using the application's supported update path.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Import or restore data:</span> determine whether the target already contains earlier imported rows and what the source's merge policy is. Test the complete restore plan in an isolated destination.<br />
</li>
</ul>
Do not invent a new business identifier just to suppress an error. The lab's second identifier was deliberately a separate synthetic record; that does not make renaming a real customer's reference a valid repair.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">4. What our private test demonstrated</span><br />
We used <span style="font-weight: bold;" class="mycode_b">MariaDB 10.11.10</span> and a disposable two-column data example with an auto-increment primary key and an additional unique reference index. Initially AF-LAB-001 had value 10.<br />
<ul class="mycode_list"><li>A normal INSERT of AF-LAB-001 with value 20 returned <span style="font-weight: bold;" class="mycode_b">1062</span>. A read-back confirmed the existing value remained <span style="font-weight: bold;" class="mycode_b">10</span>.<br />
</li>
<li>The same duplicate with <span style="font-weight: bold;" class="mycode_b">INSERT IGNORE</span> reported <span style="font-weight: bold;" class="mycode_b">zero affected rows</span> and warning <span style="font-weight: bold;" class="mycode_b">1062</span>. A read-back again showed only the existing value 10: the proposed value 20 was not saved.<br />
</li>
<li>An intentionally distinct AF-LAB-002 record with value 20 inserted successfully. The final reference/value pairs were <span style="font-weight: bold;" class="mycode_b">AF-LAB-001 → 10</span> and <span style="font-weight: bold;" class="mycode_b">AF-LAB-002 → 20</span>.<br />
</li>
</ul>
The unique index remained in place throughout. These were single-row, autocommit statements against a private fixture, not a test of a real import, concurrent application requests or multi-statement rollback handling. The disposable table was removed and its connection closed afterward. No global settings changed, and the normal HTTPS website returned 200.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">5. Understand why common shortcuts change behavior</span><ul class="mycode_list"><li><span style="font-weight: bold;" class="mycode_b">INSERT IGNORE:</span> our test showed that a duplicate can become a warning while the row is not inserted. Review affected rows, warnings and final data; a command completing without an error is not proof all input was saved.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">ON DUPLICATE KEY UPDATE:</span> this intentionally updates on a key conflict. That can be appropriate only when its identity and update semantics match the application. It is not a harmless switch for any failed import.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">REPLACE:</span> this has replacement behavior involving deletion and insertion of conflicting rows. Do not treat it as a generic in-place update; review relationships, triggers and application consequences first.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Dropping uniqueness:</span> removing an intended unique index can permit invalid duplicates. Keep the integrity rule unless an independently reviewed schema-design change actually requires something different.<br />
</li>
</ul>
Only the ordinary INSERT and INSERT IGNORE paths were tested here. The other options are design considerations, not verified repairs for your application.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">6. Check repeated imports and concurrent requests</span><br />
For an import, record where it stopped and whether earlier statements committed. Re-running a partially applied file can encounter records already present. Do not empty a live database or delete the conflicting row without a validated restore or merge plan and backup.<br />
<br />
For an application, two requests can race even when each first checks whether a value exists. Retain the database constraint and handle the conflict according to the application's intended operation. An existence check alone is not a concurrency guarantee.<br />
<br />
If the conflict is specifically on PRIMARY, inspect how that identifier was supplied and the deployment/import history. Do not reset auto-increment values or renumber related records merely because the error mentions a duplicate.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">7. Apply one justified correction and read the data back</span><br />
Back up affected data and configuration before any real corrective write. Use the application's supported identity and authorization checks. If a restore is intended, rehearse it in an isolated database and verify counts, relationships and representative records.<br />
<br />
After the correction, check the actual row values and expected outcome as well as the SQL result. Inspect warnings in the same relevant session where appropriate. Confirm the unique key is retained and unrelated data is unchanged.<br />
<br />
Our lab used a distinct synthetic record because it represented a new item. A real repeated request may instead need to return the existing result, and a real update may need a specifically authorized change. Choose the behavior from the business operation, not the easiest way to silence 1062.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">For a support request</span><br />
Include the database version, key name, operation type, timestamp, whether the target already held data and a redacted error. Do not share passwords, complete SQL dumps or customer records.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Related guides</span><br />
<a href="https://adminsforum.com/Thread-guide-import-a-sql-database-file-in-aapanel-step-by-step" target="_blank" rel="noopener" class="mycode_url">Import a SQL database file in aaPanel</a><br />
<a href="https://adminsforum.com/Thread-guide-back-up-and-restore-a-database-in-aapanel-free-edition" target="_blank" rel="noopener" class="mycode_url">Back up and restore a database</a><br />
<a href="https://adminsforum.com/Thread-guide-tune-mariadb-queries-in-aapanel-with-explain-and-index-tests" target="_blank" rel="noopener" class="mycode_url">Review query plans and indexes</a><br />
<br />
<span style="font-weight: bold;" class="mycode_b">Technical references</span><br />
<a href="https://mariadb.com/docs/server/reference/error-codes/mariadb-error-codes-1000-to-1099/e1062" target="_blank" rel="noopener" class="mycode_url">MariaDB error 1062</a><br />
<a href="https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/inserting-loading-data/insert-ignore" target="_blank" rel="noopener" class="mycode_url">INSERT IGNORE behavior</a><br />
<a href="https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/inserting-loading-data/insert-on-duplicate-key-update" target="_blank" rel="noopener" class="mycode_url">ON DUPLICATE KEY UPDATE behavior</a><br />
<a href="https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/changing-deleting-data/replace" target="_blank" rel="noopener" class="mycode_url">REPLACE semantics</a>]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[Fix MariaDB Lock Wait Timeout Error 1205 in aaPanel]]></title>
			<link>https://adminsforum.com/Thread-guide-fix-mariadb-lock-wait-timeout-error-1205-in-aapanel</link>
			<pubDate>Thu, 15 Oct 2026 14:07:57 +0800</pubDate>
			<dc:creator><![CDATA[<a href="https://adminsforum.com/member.php?action=profile&uid=2">DEV</a>]]></dc:creator>
			<guid isPermaLink="false">https://adminsforum.com/Thread-guide-fix-mariadb-lock-wait-timeout-error-1205-in-aapanel</guid>
			<description><![CDATA[<span style="font-weight: bold;" class="mycode_b">MariaDB error 1205 means a lock wait exceeded its applicable allowance. Identify what is blocked, who holds the needed lock and what happened to the transaction before retrying.</span><br />
<br />
A lock-wait timeout is not the same as error 1213, a detected deadlock. This guide demonstrates an InnoDB row-lock timeout in a separate lab database, including an earlier update that remained pending until explicit rollback. Do not deliberately block live application tables to reproduce it.<br />
<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=331" target="_blank" title="">database-lockwait-20261015.jpg</a> (Size: 126.1 KB / Downloads: 4)
<!-- end: postbit_attachments_attachment --><br />
<span style="font-style: italic;" class="mycode_i">Original AdminsForum private lab evidence, formatted as a transcript rather than a screenshot.</span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">1. Confirm the error and incident time</span><br />
Record the application action, time and timezone, job or request identifier and exact database error. A website may expose only a generic 500, so inspect the application's private log and correlate it with the website logs in aaPanel.<br />
<br />
Under <span style="font-weight: bold;" class="mycode_b">Website → PHP Project</span>, locate the affected site and open its <span style="font-weight: bold;" class="mycode_b">Log</span> control. Panel labels can vary. Do not publish raw SQL, user values, credentials or full log dumps.<br />
<br />
The error being investigated is:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>1205 / HY000
Lock wait timeout exceeded; try restarting transaction</code></div></div>A long request is not sufficient evidence of this error. Also establish which kind of lock is involved: this lab tested an InnoDB record lock, not every metadata or table-lock situation that can produce a timeout.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">2. Understand blocking without a deadlock</span><br />
One transaction can hold a row lock while another waits for it. The holder does not have to be waiting for the second transaction; there may be no circular dependency. If the applicable wait expires first, the waiting statement fails.<br />
<br />
An application that begins a transaction and leaves it open while doing other work can retain locks longer than intended. A currently idle-looking connection may still own an open transaction. Identify the transaction lifecycle rather than assuming only a visibly running SQL statement can block another request.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">3. Inspect the relevant live transaction while it is waiting</span><br />
An authorized database administrator can inspect the InnoDB transaction information. For a known application connection ID, an illustrative scoped query is:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>SELECT trx_id, trx_state, trx_started, trx_wait_started,
       trx_mysql_thread_id
FROM information_schema.INNODB_TRX
WHERE trx_mysql_thread_id = 12345;</code></div></div>Replace 12345 with the actual connection identified for the incident. Do not guess IDs or assume the phpMyAdmin connection is the same connection serving a website request. Visibility depends on privileges and version; ask the database administrator for the appropriate redacted evidence rather than granting a website account broad access.<br />
<br />
In our test the known waiting connection appeared as <span style="font-weight: bold;" class="mycode_b">LOCK WAIT</span>. This is a point-in-time view: after the statement times out or the holder finishes, the same evidence may no longer be present. An administrator may need to correlate transaction and lock-wait information to identify the blocker. Do not publish server-wide diagnostic output containing unrelated queries.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">4. Check the effective timeout and rollback behavior</span><br />
For an authorized session, these read-only checks show relevant settings:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>SELECT @@SESSION.innodb_lock_wait_timeout;
SELECT @@GLOBAL.innodb_rollback_on_timeout;</code></div></div>The first query describes the session running it. It does not prove a different pooled application connection uses the same timeout.<br />
<br />
For the InnoDB timeout behavior documented by MariaDB, a timeout normally rolls back the failing statement rather than all earlier work in the transaction. With innodb_rollback_on_timeout enabled, the entire transaction can be rolled back. Confirm the actual setting and your application's transaction state before retrying.<br />
<br />
Do not assume the instruction “try restarting transaction” means earlier work disappeared automatically. This is a material difference from a detected deadlock's transaction rollback.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">5. What our isolated lab test proved</span><br />
We used <span style="font-weight: bold;" class="mycode_b">MariaDB 10.11.10</span> and one disposable two-row InnoDB table inside the existing separate performance-test database. A holding connection updated row 1 without committing. A waiting transaction first updated row 2, then attempted row 1.<br />
<ul class="mycode_list"><li>Only the waiting test connection received a <span style="font-weight: bold;" class="mycode_b">session-local two-second lock-wait limit</span>. The blocked update returned <span style="font-weight: bold;" class="mycode_b">1205 after 2.004 seconds</span>.<br />
</li>
<li>The server's existing rollback-on-timeout value was <span style="font-weight: bold;" class="mycode_b">0</span>. Before our explicit rollback, the waiter could still see its earlier uncommitted row-2 increment as <span style="font-weight: bold;" class="mycode_b">1</span>.<br />
</li>
<li>We explicitly rolled back the waiter and the holder. An independent check then saw both row values at <span style="font-weight: bold;" class="mycode_b">0</span>.<br />
</li>
<li>With the blocker released, a fresh complete transaction updated both rows and committed. Both final values were <span style="font-weight: bold;" class="mycode_b">1</span>.<br />
</li>
</ul>
This was one coordinated timeout, not a production performance benchmark or an automatic-retry implementation. The disposable table was removed and all test connections closed. No global settings changed; we also checked the relevant global timeout and rollback values remained the same. The normal HTTPS website returned 200 afterward.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">6. Correct the cause of excessive lock duration</span><br />
Review where the blocking transaction begins and ends. Check for missing commit or rollback handling, unnecessarily large batches, external network calls inside a transaction and competing operations on the same records.<br />
<br />
Use representative staging data to investigate query plans and the records affected. An inefficient scan can increase contention, but adding an index without examining the real workload is not a guaranteed repair. Keep transaction boundaries aligned with the application's consistency requirements.<br />
<br />
Do not kill arbitrary database sessions or restart MariaDB as a first response. Ending a holder can trigger rollback and affect other requests. A production intervention needs identification of the owner and the consequences, not just a large elapsed-time number.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">7. Recover the whole logical operation deliberately</span><br />
Use the application's supported transaction handling to return to a known state. If retry is appropriate, apply a bounded retry policy to the complete logical transaction after resolving or allowing for the blocker. Include short backoff and a clear failure path rather than an infinite retry loop.<br />
<br />
Do not commit earlier partial work accidentally after catching only the failed statement. Also account for external effects: database rollback cannot unsend an email or undo an external payment. Idempotency and application semantics need their own tests.<br />
<br />
Our lab explicitly rolled back before the clean retry. It did not validate any real application's error-handling code or business operation.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">8. Change wait budgets only for a measured reason</span><br />
A longer timeout allows more waiting; it does not release the blocking lock. It can also hold application workers and connections for longer. Consider a change only after understanding the workload, transaction duration and user-facing request budget.<br />
<br />
Record the previous value and scope. Session settings and global defaults affect different connections; existing pooled connections may behave differently from newly created ones. Do not apply the lab's two-second value to a live site as a recommendation. Changing global rollback behavior also changes semantics and is outside this tested fix.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">9. Verify data and cleanup</span><br />
Test the original operation and a controlled competing path in staging. Check final values, explicit rollback behavior, bounded retries and application logs. An HTTP 200 response or the absence of one timeout does not prove the transaction completed correctly.<br />
<br />
Monitor representative traffic after a justified change and keep a rollback plan. Remove disposable test tables and close diagnostic transactions. Do not leave a manual transaction open in a SQL tool after testing.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">For a support request</span><br />
Include the database version, error code, time, relevant transaction boundaries, scoped redacted wait evidence and recent changes. Do not share full customer SQL or database passwords.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Related guides</span><br />
<a href="https://adminsforum.com/Thread-guide-fix-mariadb-deadlock-error-1213-in-aapanel" target="_blank" rel="noopener" class="mycode_url">Distinguish MariaDB deadlock error 1213</a><br />
<a href="https://adminsforum.com/Thread-guide-tune-mariadb-queries-in-aapanel-with-explain-and-index-tests" target="_blank" rel="noopener" class="mycode_url">Inspect query plans and index changes</a><br />
<a href="https://adminsforum.com/Thread-guide-check-website-logs-in-aapanel-to-troubleshoot-site-errors" target="_blank" rel="noopener" class="mycode_url">Correlate website errors with logs</a><br />
<br />
<span style="font-weight: bold;" class="mycode_b">Technical references</span><br />
<a href="https://mariadb.com/docs/server/reference/error-codes/mariadb-error-codes-1200-to-1299/e1205" target="_blank" rel="noopener" class="mycode_url">MariaDB error 1205</a><br />
<a href="https://mariadb.com/docs/server/server-usage/storage-engines/innodb/innodb-system-variables" target="_blank" rel="noopener" class="mycode_url">InnoDB lock-wait and rollback settings</a><br />
<a href="https://mariadb.com/docs/server/reference/system-tables/information-schema/information-schema-tables/information-schema-innodb-tables/information-schema-innodb_trx-table" target="_blank" rel="noopener" class="mycode_url">InnoDB transaction diagnostics</a><br />
<a href="https://mariadb.com/docs/server/reference/sql-statements/transactions/rollback" target="_blank" rel="noopener" class="mycode_url">MariaDB ROLLBACK behavior</a>]]></description>
			<content:encoded><![CDATA[<span style="font-weight: bold;" class="mycode_b">MariaDB error 1205 means a lock wait exceeded its applicable allowance. Identify what is blocked, who holds the needed lock and what happened to the transaction before retrying.</span><br />
<br />
A lock-wait timeout is not the same as error 1213, a detected deadlock. This guide demonstrates an InnoDB row-lock timeout in a separate lab database, including an earlier update that remained pending until explicit rollback. Do not deliberately block live application tables to reproduce it.<br />
<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=331" target="_blank" title="">database-lockwait-20261015.jpg</a> (Size: 126.1 KB / Downloads: 4)
<!-- end: postbit_attachments_attachment --><br />
<span style="font-style: italic;" class="mycode_i">Original AdminsForum private lab evidence, formatted as a transcript rather than a screenshot.</span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">1. Confirm the error and incident time</span><br />
Record the application action, time and timezone, job or request identifier and exact database error. A website may expose only a generic 500, so inspect the application's private log and correlate it with the website logs in aaPanel.<br />
<br />
Under <span style="font-weight: bold;" class="mycode_b">Website → PHP Project</span>, locate the affected site and open its <span style="font-weight: bold;" class="mycode_b">Log</span> control. Panel labels can vary. Do not publish raw SQL, user values, credentials or full log dumps.<br />
<br />
The error being investigated is:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>1205 / HY000
Lock wait timeout exceeded; try restarting transaction</code></div></div>A long request is not sufficient evidence of this error. Also establish which kind of lock is involved: this lab tested an InnoDB record lock, not every metadata or table-lock situation that can produce a timeout.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">2. Understand blocking without a deadlock</span><br />
One transaction can hold a row lock while another waits for it. The holder does not have to be waiting for the second transaction; there may be no circular dependency. If the applicable wait expires first, the waiting statement fails.<br />
<br />
An application that begins a transaction and leaves it open while doing other work can retain locks longer than intended. A currently idle-looking connection may still own an open transaction. Identify the transaction lifecycle rather than assuming only a visibly running SQL statement can block another request.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">3. Inspect the relevant live transaction while it is waiting</span><br />
An authorized database administrator can inspect the InnoDB transaction information. For a known application connection ID, an illustrative scoped query is:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>SELECT trx_id, trx_state, trx_started, trx_wait_started,
       trx_mysql_thread_id
FROM information_schema.INNODB_TRX
WHERE trx_mysql_thread_id = 12345;</code></div></div>Replace 12345 with the actual connection identified for the incident. Do not guess IDs or assume the phpMyAdmin connection is the same connection serving a website request. Visibility depends on privileges and version; ask the database administrator for the appropriate redacted evidence rather than granting a website account broad access.<br />
<br />
In our test the known waiting connection appeared as <span style="font-weight: bold;" class="mycode_b">LOCK WAIT</span>. This is a point-in-time view: after the statement times out or the holder finishes, the same evidence may no longer be present. An administrator may need to correlate transaction and lock-wait information to identify the blocker. Do not publish server-wide diagnostic output containing unrelated queries.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">4. Check the effective timeout and rollback behavior</span><br />
For an authorized session, these read-only checks show relevant settings:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>SELECT @@SESSION.innodb_lock_wait_timeout;
SELECT @@GLOBAL.innodb_rollback_on_timeout;</code></div></div>The first query describes the session running it. It does not prove a different pooled application connection uses the same timeout.<br />
<br />
For the InnoDB timeout behavior documented by MariaDB, a timeout normally rolls back the failing statement rather than all earlier work in the transaction. With innodb_rollback_on_timeout enabled, the entire transaction can be rolled back. Confirm the actual setting and your application's transaction state before retrying.<br />
<br />
Do not assume the instruction “try restarting transaction” means earlier work disappeared automatically. This is a material difference from a detected deadlock's transaction rollback.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">5. What our isolated lab test proved</span><br />
We used <span style="font-weight: bold;" class="mycode_b">MariaDB 10.11.10</span> and one disposable two-row InnoDB table inside the existing separate performance-test database. A holding connection updated row 1 without committing. A waiting transaction first updated row 2, then attempted row 1.<br />
<ul class="mycode_list"><li>Only the waiting test connection received a <span style="font-weight: bold;" class="mycode_b">session-local two-second lock-wait limit</span>. The blocked update returned <span style="font-weight: bold;" class="mycode_b">1205 after 2.004 seconds</span>.<br />
</li>
<li>The server's existing rollback-on-timeout value was <span style="font-weight: bold;" class="mycode_b">0</span>. Before our explicit rollback, the waiter could still see its earlier uncommitted row-2 increment as <span style="font-weight: bold;" class="mycode_b">1</span>.<br />
</li>
<li>We explicitly rolled back the waiter and the holder. An independent check then saw both row values at <span style="font-weight: bold;" class="mycode_b">0</span>.<br />
</li>
<li>With the blocker released, a fresh complete transaction updated both rows and committed. Both final values were <span style="font-weight: bold;" class="mycode_b">1</span>.<br />
</li>
</ul>
This was one coordinated timeout, not a production performance benchmark or an automatic-retry implementation. The disposable table was removed and all test connections closed. No global settings changed; we also checked the relevant global timeout and rollback values remained the same. The normal HTTPS website returned 200 afterward.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">6. Correct the cause of excessive lock duration</span><br />
Review where the blocking transaction begins and ends. Check for missing commit or rollback handling, unnecessarily large batches, external network calls inside a transaction and competing operations on the same records.<br />
<br />
Use representative staging data to investigate query plans and the records affected. An inefficient scan can increase contention, but adding an index without examining the real workload is not a guaranteed repair. Keep transaction boundaries aligned with the application's consistency requirements.<br />
<br />
Do not kill arbitrary database sessions or restart MariaDB as a first response. Ending a holder can trigger rollback and affect other requests. A production intervention needs identification of the owner and the consequences, not just a large elapsed-time number.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">7. Recover the whole logical operation deliberately</span><br />
Use the application's supported transaction handling to return to a known state. If retry is appropriate, apply a bounded retry policy to the complete logical transaction after resolving or allowing for the blocker. Include short backoff and a clear failure path rather than an infinite retry loop.<br />
<br />
Do not commit earlier partial work accidentally after catching only the failed statement. Also account for external effects: database rollback cannot unsend an email or undo an external payment. Idempotency and application semantics need their own tests.<br />
<br />
Our lab explicitly rolled back before the clean retry. It did not validate any real application's error-handling code or business operation.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">8. Change wait budgets only for a measured reason</span><br />
A longer timeout allows more waiting; it does not release the blocking lock. It can also hold application workers and connections for longer. Consider a change only after understanding the workload, transaction duration and user-facing request budget.<br />
<br />
Record the previous value and scope. Session settings and global defaults affect different connections; existing pooled connections may behave differently from newly created ones. Do not apply the lab's two-second value to a live site as a recommendation. Changing global rollback behavior also changes semantics and is outside this tested fix.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">9. Verify data and cleanup</span><br />
Test the original operation and a controlled competing path in staging. Check final values, explicit rollback behavior, bounded retries and application logs. An HTTP 200 response or the absence of one timeout does not prove the transaction completed correctly.<br />
<br />
Monitor representative traffic after a justified change and keep a rollback plan. Remove disposable test tables and close diagnostic transactions. Do not leave a manual transaction open in a SQL tool after testing.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">For a support request</span><br />
Include the database version, error code, time, relevant transaction boundaries, scoped redacted wait evidence and recent changes. Do not share full customer SQL or database passwords.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Related guides</span><br />
<a href="https://adminsforum.com/Thread-guide-fix-mariadb-deadlock-error-1213-in-aapanel" target="_blank" rel="noopener" class="mycode_url">Distinguish MariaDB deadlock error 1213</a><br />
<a href="https://adminsforum.com/Thread-guide-tune-mariadb-queries-in-aapanel-with-explain-and-index-tests" target="_blank" rel="noopener" class="mycode_url">Inspect query plans and index changes</a><br />
<a href="https://adminsforum.com/Thread-guide-check-website-logs-in-aapanel-to-troubleshoot-site-errors" target="_blank" rel="noopener" class="mycode_url">Correlate website errors with logs</a><br />
<br />
<span style="font-weight: bold;" class="mycode_b">Technical references</span><br />
<a href="https://mariadb.com/docs/server/reference/error-codes/mariadb-error-codes-1200-to-1299/e1205" target="_blank" rel="noopener" class="mycode_url">MariaDB error 1205</a><br />
<a href="https://mariadb.com/docs/server/server-usage/storage-engines/innodb/innodb-system-variables" target="_blank" rel="noopener" class="mycode_url">InnoDB lock-wait and rollback settings</a><br />
<a href="https://mariadb.com/docs/server/reference/system-tables/information-schema/information-schema-tables/information-schema-innodb-tables/information-schema-innodb_trx-table" target="_blank" rel="noopener" class="mycode_url">InnoDB transaction diagnostics</a><br />
<a href="https://mariadb.com/docs/server/reference/sql-statements/transactions/rollback" target="_blank" rel="noopener" class="mycode_url">MariaDB ROLLBACK behavior</a>]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[Fix MariaDB Deadlock Error 1213 in aaPanel]]></title>
			<link>https://adminsforum.com/Thread-guide-fix-mariadb-deadlock-error-1213-in-aapanel</link>
			<pubDate>Thu, 15 Oct 2026 13:58:53 +0800</pubDate>
			<dc:creator><![CDATA[<a href="https://adminsforum.com/member.php?action=profile&uid=2">DEV</a>]]></dc:creator>
			<guid isPermaLink="false">https://adminsforum.com/Thread-guide-fix-mariadb-deadlock-error-1213-in-aapanel</guid>
			<description><![CDATA[<span style="font-weight: bold;" class="mycode_b">MariaDB error 1213 means a deadlock was detected and a transaction was chosen for rollback. Investigate the competing transactions and application retry behavior; increasing a timeout does not remove a circular lock dependency.</span><br />
<br />
This guide uses a two-row InnoDB experiment in a separate lab database. It shows one way opposite update orders can deadlock, then verifies a consistent-order comparison. Do not reproduce deliberate lock conflicts against your live application tables.<br />
<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=330" target="_blank" title="">database-deadlock-20261015.jpg</a> (Size: 125.88 KB / Downloads: 3)
<!-- end: postbit_attachments_attachment --><br />
<span style="font-style: italic;" class="mycode_i">Original AdminsForum private lab results, formatted as a transcript rather than a screenshot.</span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">1. Confirm the actual database error</span><br />
Record the application action, time and timezone, request or job identifier and exact database error code. An application may show only a generic 500, so inspect its private logs as well as the website error log.<br />
<br />
In aaPanel open the affected site's <span style="font-weight: bold;" class="mycode_b">Log</span> control under <span style="font-weight: bold;" class="mycode_b">Website → PHP Project</span> and correlate the incident time. If the application has its own log, use that too. Avoid publishing SQL containing customer data, authentication details or private values.<br />
<br />
MariaDB identifies this error as:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>1213 / SQLSTATE 40001 / ER_LOCK_DEADLOCK
Deadlock found when trying to get lock; try restarting transaction</code></div></div>Do not confuse it with error 1205, a lock-wait timeout. A slow query or high CPU reading does not by itself prove a deadlock occurred.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">2. Understand the circular wait</span><br />
A simplified two-row case looks like this:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>Transaction A holds row 1 and requests row 2.
Transaction B holds row 2 and requests row 1.</code></div></div>Each transaction is waiting for a lock held by the other. InnoDB can break this cycle by rolling back a victim. The selected victim can vary; do not hard-code application logic around a particular worker always losing.<br />
<br />
Consistent ordering can remove this particular cycle, but real transactions can involve multiple tables, indexes, ranges and triggers. Fix the demonstrated conflict rather than assuming every deadlock is a two-row problem.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">3. Inspect the most recent InnoDB deadlock report</span><br />
Through an authorized database administration session, run the read-only diagnostic:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>SHOW ENGINE INNODB STATUS;</code></div></div>Inspect the <span style="font-weight: bold;" class="mycode_b">LATEST DETECTED DEADLOCK</span> section. It can identify the participating transactions, SQL statements, held or requested locks and the rollback victim. Check its timestamp and affected table against your incident.<br />
<br />
This output is server-wide and can contain sensitive SQL. Keep the full report private and share a narrowly redacted excerpt. The latest report may belong to another application or a later event; it is not a complete history of every deadlock. If access is denied, ask the database administrator for the relevant excerpt rather than granting broad privileges to a website account.<br />
<br />
For repeated incidents, an administrator can assess dedicated deadlock logging and its retention separately. Our experiment did not enable global logging or collect unrelated database queries.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">4. What our isolated aaPanel lab tested</span><br />
The lab ran <span style="font-weight: bold;" class="mycode_b">MariaDB 10.11.10</span>. We created one disposable InnoDB table with two primary-key rows inside the existing separate performance-test database. Only the owned test rows were updated. No production application table or global database setting was changed.<br />
<ul class="mycode_list"><li>Two transactions first updated different rows, then attempted the other row in opposite order. In this run, <span style="font-weight: bold;" class="mycode_b">A received error 1213 and rolled back; B committed</span>. The latest deadlock section referenced the lab table.<br />
</li>
<li>We reset the two test values, then ran both transactions in the same order: <span style="font-weight: bold;" class="mycode_b">row 1 followed by row 2</span>. Both committed in this comparison.<br />
</li>
<li>The final values were <span style="font-weight: bold;" class="mycode_b">2 for row 1 and 2 for row 2</span>, confirming that both successful transactions applied their increments.<br />
</li>
</ul>
This was a coordinated, bounded demonstration with session-local lock-wait limits. It was not a production concurrency benchmark or proof that consistent ordering prevents every possible deadlock. The disposable table was removed and connections closed afterward. No global setting changed, and the normal HTTPS website returned 200.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">5. Review the complete application transaction</span><br />
Find where the transaction begins, what rows and tables it touches, and when it commits or rolls back. Include ORM operations, background jobs and triggers that can acquire additional locks.<br />
<br />
Compare the order used by competing code paths. Where the application's correctness permits it, make related operations acquire locks in a consistent order across those paths. Keep transactions focused and avoid unnecessary waiting or external network calls while holding locks.<br />
<br />
Also review query plans and indexes when transactions scan or lock more records than expected. Adding an index is not an automatic deadlock cure: confirm the actual access pattern and test correctness and write overhead in staging.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">6. Handle retry at the transaction boundary</span><br />
An application should recognize a deadlock and handle the rolled-back transaction deliberately. If retry is appropriate for the operation, retry the complete logical transaction using the framework or driver's supported transaction mechanism, with a bounded number of attempts and a short backoff.<br />
<br />
Do not blindly rerun only the last SQL statement or retry indefinitely. Emails, payments and other external side effects need separate idempotency and consistency handling; a database rollback does not undo an external action. Confirm the application's transaction state before issuing another attempt.<br />
<br />
Our lab recorded the deadlock and rollback explicitly; it did not implement or validate a real application's automatic retry strategy. Test that separately using controlled data.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">7. Avoid unrelated server changes</span><br />
Do not restart MariaDB, disable deadlock detection or increase connection and timeout limits just because one request reported 1213. Those changes do not repair a demonstrated circular lock order and can affect other sites.<br />
<br />
Changing isolation levels also changes application semantics. Treat it as an application-design decision requiring appropriate testing, not a generic panel tuning step. Preserve transaction integrity and existing safeguards while gathering evidence.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">8. Verify with representative controlled operations</span><br />
After a code or query change, test the original operation and competing path in staging with bounded concurrency. Check final data, rollback behavior and retry limits, not merely the absence of a browser error. Monitor the relevant deadlock evidence over a representative period.<br />
<br />
A single successful pair is useful evidence for a small reproduction, not proof that all workload conflicts are gone. Keep the original code/configuration and a tested rollback plan. Remove disposable test tables and do not delete or unlock real business data to make a test appear successful.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">For a useful support request</span><br />
Provide the database version, error code, time, redacted deadlock excerpt, transaction boundaries and recent application changes. Describe expected data consistency. Do not include database passwords, full customer SQL or server-wide diagnostic dumps.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Related guides</span><br />
<a href="https://adminsforum.com/Thread-guide-tune-mariadb-queries-in-aapanel-with-explain-and-index-tests" target="_blank" rel="noopener" class="mycode_url">Measure MariaDB query plans and index changes</a><br />
<a href="https://adminsforum.com/Thread-guide-check-website-logs-in-aapanel-to-troubleshoot-site-errors" target="_blank" rel="noopener" class="mycode_url">Correlate website errors with logs</a><br />
<a href="https://adminsforum.com/Thread-guide-fix-php-http-500-errors-in-aapanel-using-error-logs" target="_blank" rel="noopener" class="mycode_url">Investigate PHP HTTP 500 errors</a><br />
<br />
<span style="font-weight: bold;" class="mycode_b">Technical references</span><br />
<a href="https://mariadb.com/docs/server/reference/error-codes/mariadb-error-codes-1200-to-1299/e1213" target="_blank" rel="noopener" class="mycode_url">MariaDB error 1213</a><br />
<a href="https://mariadb.com/docs/server/reference/sql-statements/administrative-sql-statements/show/show-engine-innodb-status" target="_blank" rel="noopener" class="mycode_url">SHOW ENGINE INNODB STATUS documentation</a><br />
<a href="https://mariadb.com/docs/server/server-usage/storage-engines/innodb/innodb-system-variables" target="_blank" rel="noopener" class="mycode_url">InnoDB lock-wait and deadlock settings</a>]]></description>
			<content:encoded><![CDATA[<span style="font-weight: bold;" class="mycode_b">MariaDB error 1213 means a deadlock was detected and a transaction was chosen for rollback. Investigate the competing transactions and application retry behavior; increasing a timeout does not remove a circular lock dependency.</span><br />
<br />
This guide uses a two-row InnoDB experiment in a separate lab database. It shows one way opposite update orders can deadlock, then verifies a consistent-order comparison. Do not reproduce deliberate lock conflicts against your live application tables.<br />
<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=330" target="_blank" title="">database-deadlock-20261015.jpg</a> (Size: 125.88 KB / Downloads: 3)
<!-- end: postbit_attachments_attachment --><br />
<span style="font-style: italic;" class="mycode_i">Original AdminsForum private lab results, formatted as a transcript rather than a screenshot.</span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">1. Confirm the actual database error</span><br />
Record the application action, time and timezone, request or job identifier and exact database error code. An application may show only a generic 500, so inspect its private logs as well as the website error log.<br />
<br />
In aaPanel open the affected site's <span style="font-weight: bold;" class="mycode_b">Log</span> control under <span style="font-weight: bold;" class="mycode_b">Website → PHP Project</span> and correlate the incident time. If the application has its own log, use that too. Avoid publishing SQL containing customer data, authentication details or private values.<br />
<br />
MariaDB identifies this error as:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>1213 / SQLSTATE 40001 / ER_LOCK_DEADLOCK
Deadlock found when trying to get lock; try restarting transaction</code></div></div>Do not confuse it with error 1205, a lock-wait timeout. A slow query or high CPU reading does not by itself prove a deadlock occurred.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">2. Understand the circular wait</span><br />
A simplified two-row case looks like this:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>Transaction A holds row 1 and requests row 2.
Transaction B holds row 2 and requests row 1.</code></div></div>Each transaction is waiting for a lock held by the other. InnoDB can break this cycle by rolling back a victim. The selected victim can vary; do not hard-code application logic around a particular worker always losing.<br />
<br />
Consistent ordering can remove this particular cycle, but real transactions can involve multiple tables, indexes, ranges and triggers. Fix the demonstrated conflict rather than assuming every deadlock is a two-row problem.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">3. Inspect the most recent InnoDB deadlock report</span><br />
Through an authorized database administration session, run the read-only diagnostic:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>SHOW ENGINE INNODB STATUS;</code></div></div>Inspect the <span style="font-weight: bold;" class="mycode_b">LATEST DETECTED DEADLOCK</span> section. It can identify the participating transactions, SQL statements, held or requested locks and the rollback victim. Check its timestamp and affected table against your incident.<br />
<br />
This output is server-wide and can contain sensitive SQL. Keep the full report private and share a narrowly redacted excerpt. The latest report may belong to another application or a later event; it is not a complete history of every deadlock. If access is denied, ask the database administrator for the relevant excerpt rather than granting broad privileges to a website account.<br />
<br />
For repeated incidents, an administrator can assess dedicated deadlock logging and its retention separately. Our experiment did not enable global logging or collect unrelated database queries.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">4. What our isolated aaPanel lab tested</span><br />
The lab ran <span style="font-weight: bold;" class="mycode_b">MariaDB 10.11.10</span>. We created one disposable InnoDB table with two primary-key rows inside the existing separate performance-test database. Only the owned test rows were updated. No production application table or global database setting was changed.<br />
<ul class="mycode_list"><li>Two transactions first updated different rows, then attempted the other row in opposite order. In this run, <span style="font-weight: bold;" class="mycode_b">A received error 1213 and rolled back; B committed</span>. The latest deadlock section referenced the lab table.<br />
</li>
<li>We reset the two test values, then ran both transactions in the same order: <span style="font-weight: bold;" class="mycode_b">row 1 followed by row 2</span>. Both committed in this comparison.<br />
</li>
<li>The final values were <span style="font-weight: bold;" class="mycode_b">2 for row 1 and 2 for row 2</span>, confirming that both successful transactions applied their increments.<br />
</li>
</ul>
This was a coordinated, bounded demonstration with session-local lock-wait limits. It was not a production concurrency benchmark or proof that consistent ordering prevents every possible deadlock. The disposable table was removed and connections closed afterward. No global setting changed, and the normal HTTPS website returned 200.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">5. Review the complete application transaction</span><br />
Find where the transaction begins, what rows and tables it touches, and when it commits or rolls back. Include ORM operations, background jobs and triggers that can acquire additional locks.<br />
<br />
Compare the order used by competing code paths. Where the application's correctness permits it, make related operations acquire locks in a consistent order across those paths. Keep transactions focused and avoid unnecessary waiting or external network calls while holding locks.<br />
<br />
Also review query plans and indexes when transactions scan or lock more records than expected. Adding an index is not an automatic deadlock cure: confirm the actual access pattern and test correctness and write overhead in staging.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">6. Handle retry at the transaction boundary</span><br />
An application should recognize a deadlock and handle the rolled-back transaction deliberately. If retry is appropriate for the operation, retry the complete logical transaction using the framework or driver's supported transaction mechanism, with a bounded number of attempts and a short backoff.<br />
<br />
Do not blindly rerun only the last SQL statement or retry indefinitely. Emails, payments and other external side effects need separate idempotency and consistency handling; a database rollback does not undo an external action. Confirm the application's transaction state before issuing another attempt.<br />
<br />
Our lab recorded the deadlock and rollback explicitly; it did not implement or validate a real application's automatic retry strategy. Test that separately using controlled data.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">7. Avoid unrelated server changes</span><br />
Do not restart MariaDB, disable deadlock detection or increase connection and timeout limits just because one request reported 1213. Those changes do not repair a demonstrated circular lock order and can affect other sites.<br />
<br />
Changing isolation levels also changes application semantics. Treat it as an application-design decision requiring appropriate testing, not a generic panel tuning step. Preserve transaction integrity and existing safeguards while gathering evidence.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">8. Verify with representative controlled operations</span><br />
After a code or query change, test the original operation and competing path in staging with bounded concurrency. Check final data, rollback behavior and retry limits, not merely the absence of a browser error. Monitor the relevant deadlock evidence over a representative period.<br />
<br />
A single successful pair is useful evidence for a small reproduction, not proof that all workload conflicts are gone. Keep the original code/configuration and a tested rollback plan. Remove disposable test tables and do not delete or unlock real business data to make a test appear successful.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">For a useful support request</span><br />
Provide the database version, error code, time, redacted deadlock excerpt, transaction boundaries and recent application changes. Describe expected data consistency. Do not include database passwords, full customer SQL or server-wide diagnostic dumps.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Related guides</span><br />
<a href="https://adminsforum.com/Thread-guide-tune-mariadb-queries-in-aapanel-with-explain-and-index-tests" target="_blank" rel="noopener" class="mycode_url">Measure MariaDB query plans and index changes</a><br />
<a href="https://adminsforum.com/Thread-guide-check-website-logs-in-aapanel-to-troubleshoot-site-errors" target="_blank" rel="noopener" class="mycode_url">Correlate website errors with logs</a><br />
<a href="https://adminsforum.com/Thread-guide-fix-php-http-500-errors-in-aapanel-using-error-logs" target="_blank" rel="noopener" class="mycode_url">Investigate PHP HTTP 500 errors</a><br />
<br />
<span style="font-weight: bold;" class="mycode_b">Technical references</span><br />
<a href="https://mariadb.com/docs/server/reference/error-codes/mariadb-error-codes-1200-to-1299/e1213" target="_blank" rel="noopener" class="mycode_url">MariaDB error 1213</a><br />
<a href="https://mariadb.com/docs/server/reference/sql-statements/administrative-sql-statements/show/show-engine-innodb-status" target="_blank" rel="noopener" class="mycode_url">SHOW ENGINE INNODB STATUS documentation</a><br />
<a href="https://mariadb.com/docs/server/server-usage/storage-engines/innodb/innodb-system-variables" target="_blank" rel="noopener" class="mycode_url">InnoDB lock-wait and deadlock settings</a>]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[Tune MariaDB Queries in aaPanel with EXPLAIN and Index Tests]]></title>
			<link>https://adminsforum.com/Thread-guide-tune-mariadb-queries-in-aapanel-with-explain-and-index-tests</link>
			<pubDate>Wed, 14 Oct 2026 20:17:01 +0800</pubDate>
			<dc:creator><![CDATA[<a href="https://adminsforum.com/member.php?action=profile&uid=2">DEV</a>]]></dc:creator>
			<guid isPermaLink="false">https://adminsforum.com/Thread-guide-tune-mariadb-queries-in-aapanel-with-explain-and-index-tests</guid>
			<description><![CDATA[<span style="font-weight: bold;" class="mycode_b">A slow website does not automatically need a larger database buffer or more connections. First identify the query, inspect its execution plan and measure a targeted change. This guide demonstrates that workflow in a separate MariaDB lab database.</span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">Tested environment</span>: aaPanel Free 8.0.7, Ubuntu 22.04.5 and MariaDB 10.11.10. MySQL and MariaDB releases differ; verify your installed version before copying configuration advice. We used 50,000 synthetic rows and changed no global database settings.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">1. Identify the database and establish a baseline</span><br />
Open aaPanel → Databases and confirm which service and database the website uses. Inspect application logs and slow queries rather than assuming the homepage represents all workloads. Administrative diagnostics require suitable database permissions; keep credentials out of commands, screenshots and public tutorials.<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>SELECT VERSION();
SHOW VARIABLES WHERE Variable_name IN
('innodb_buffer_pool_size','max_connections','slow_query_log','long_query_time');
SHOW GLOBAL STATUS WHERE Variable_name IN
('Threads_connected','Max_used_connections','Innodb_buffer_pool_reads','Innodb_buffer_pool_read_requests');</code></div></div>Our lab had a 384MiB InnoDB buffer pool, max_connections 200, slow logging enabled and a 3-second threshold. Maximum used connections was 3 at that observation. These are observations, not recommended settings for every server.<br />
Counters may accumulate since startup. Take interval snapshots under representative traffic; a one-time cache ratio is not enough to justify allocating more RAM.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">2. Find the actual slow query</span><br />
If slow logging is enabled, review its configured path through an administrator session. Logs can contain query text and user data: keep access restricted and do not upload raw logs to a public thread. A 3-second threshold will miss many shorter queries; choose a diagnostic threshold deliberately and monitor storage overhead.<br />
Find frequently repeated queries as well as individually expensive ones. Record execution count, latency and examined rows. A fast query executed thousands of times may still consume significant resources.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">3. Create a separate practice database</span><br />
Use a disposable database, never a production table, for this example. Our new database was af_performance_index_lab_20261014. In MariaDB 10.11, the sequence table below provides synthetic integers; this syntax is not a portable MySQL recipe.<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>CREATE DATABASE af_performance_index_lab_20261014;
USE af_performance_index_lab_20261014;
CREATE TABLE events (
  id INT PRIMARY KEY,
  account_id INT NOT NULL,
  status VARCHAR(16) NOT NULL,
  payload VARCHAR(100) NOT NULL
) ENGINE=InnoDB;
INSERT INTO events
SELECT seq, MOD(seq,1000),
       IF(MOD(seq,2)=0,'active','closed'), REPEAT('x',100)
FROM seq_1_to_50000;</code></div></div>Check that your chosen database name does not already exist. This example creates only synthetic data; adapt names and versions for your own isolated lab.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">4. Inspect the query plan before changing anything</span><br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>EXPLAIN SELECT SQL_NO_CACHE COUNT(*)
FROM events WHERE account_id=321 AND status='closed';</code></div></div>SQL_NO_CACHE is used here to exclude MariaDB's query-result cache; it does not empty the InnoDB buffer pool. Do not copy this clause into an incompatible database release.<br />
Our plan showed type ALL and an estimated 50,000 rows. EXPLAIN estimates are not measured execution counts, but this plan indicates a full table scan to evaluate the filters.<br />
The query returned 50 matching rows. Record the result so that a faster but incorrect rewrite is not accepted.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">5. Test a targeted composite index</span><br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>ALTER TABLE events
  ADD INDEX idx_account_status(account_id,status);
ANALYZE TABLE events;
EXPLAIN SELECT SQL_NO_CACHE COUNT(*)
FROM events WHERE account_id=321 AND status='closed';</code></div></div>The new plan used idx_account_status, type ref and an estimated 50 rows. It also reported Using index: this count query can be satisfied from the index entries needed for the filters.<br />
Index design depends on the actual predicates, sorting and joins. Column order matters for other queries using only part of a composite index. Avoid creating an index for every column: indexes use storage and add work to writes.<br />
On a large production table, building an index can consume time, space and locks. Check version-specific online DDL behavior, back up and plan the change before applying it to real data.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">6. Compare the same query</span><br />
We used MariaDB session profiling for this lab: one warmup followed by ten measured executions in each phase. The same database session setting and query were used before and after. Warm data remained possible in the buffer pool; this is not a cold-storage benchmark.<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>SET profiling=1;
SELECT SQL_NO_CACHE COUNT(*)
FROM events WHERE account_id=321 AND status='closed';
SHOW PROFILES;</code></div></div>Repeat the SELECT for your sample and inspect its reported duration. Session profiling is version-specific; use the diagnostic tools available in your actual database release. Disable temporary profiling when finished.<br />
<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=291" target="_blank" title="">database-index-comparison-20261014.jpg</a> (Size: 115.87 KB / Downloads: 5)
<!-- end: postbit_attachments_attachment --><br />
<span style="font-style: italic;" class="mycode_i">AdminsForum formatted transcript of the original lab test, not a terminal screenshot.</span><br />
<br />
The median of ten measured executions was about 12.72ms before and 0.188ms after. Both phases returned 50 rows. This supports this index for this synthetic query; it does not promise the same improvement for every website or establish production capacity.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">7. Tune resources only after reviewing evidence</span><br />
For InnoDB buffer sizing, account for the working data set and sustained physical reads, while reserving memory for PHP-FPM, Nginx, OS, mail and other services. Dedicated database-server percentage rules are unsuitable for every shared aaPanel VPS.<br />
For max_connections, inspect concurrent connections, application pooling and per-connection memory. Raising the limit can worsen overload. Our observed maximum of 3 did not justify increasing the limit of 200.<br />
Change one setting at a time, retain its original value, validate the database configuration and repeat representative workloads. Monitor swap, OOM events, errors and query latency. A restart can temporarily alter cache warmth and distort comparisons.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">8. Verify the website and retain a rollback plan</span><br />
Test real reads and writes, not just this SELECT. Compare execution plans and results, then monitor normal traffic. For our disposable table, the index can be removed with:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>ALTER TABLE events DROP INDEX idx_account_status;</code></div></div>Do not remove an existing production index without checking its other uses. We retained this isolated lab database and its index for repeatable demonstrations; no application database was modified.<br />
<br />
Continue with <a href="https://adminsforum.com/Thread-guide-tune-php-fpm-workers-in-aapanel-with-measured-memory-limits" target="_blank" rel="noopener" class="mycode_url">PHP-FPM memory limits</a> to balance the shared server, rather than tuning each service as though it owns all RAM.<br />
<br />
<br />
<span style="font-weight: bold;" class="mycode_b">References</span>: <a href="https://mariadb.com/docs/server/reference/sql-statements/administrative-sql-statements/analyze-and-explain-statements/explain" target="_blank" rel="noopener" class="mycode_url">MariaDB EXPLAIN</a> and <a href="https://mariadb.com/docs/server/reference/sql-statements/administrative-sql-statements/show/show-profiles" target="_blank" rel="noopener" class="mycode_url">SHOW PROFILES</a>.]]></description>
			<content:encoded><![CDATA[<span style="font-weight: bold;" class="mycode_b">A slow website does not automatically need a larger database buffer or more connections. First identify the query, inspect its execution plan and measure a targeted change. This guide demonstrates that workflow in a separate MariaDB lab database.</span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">Tested environment</span>: aaPanel Free 8.0.7, Ubuntu 22.04.5 and MariaDB 10.11.10. MySQL and MariaDB releases differ; verify your installed version before copying configuration advice. We used 50,000 synthetic rows and changed no global database settings.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">1. Identify the database and establish a baseline</span><br />
Open aaPanel → Databases and confirm which service and database the website uses. Inspect application logs and slow queries rather than assuming the homepage represents all workloads. Administrative diagnostics require suitable database permissions; keep credentials out of commands, screenshots and public tutorials.<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>SELECT VERSION();
SHOW VARIABLES WHERE Variable_name IN
('innodb_buffer_pool_size','max_connections','slow_query_log','long_query_time');
SHOW GLOBAL STATUS WHERE Variable_name IN
('Threads_connected','Max_used_connections','Innodb_buffer_pool_reads','Innodb_buffer_pool_read_requests');</code></div></div>Our lab had a 384MiB InnoDB buffer pool, max_connections 200, slow logging enabled and a 3-second threshold. Maximum used connections was 3 at that observation. These are observations, not recommended settings for every server.<br />
Counters may accumulate since startup. Take interval snapshots under representative traffic; a one-time cache ratio is not enough to justify allocating more RAM.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">2. Find the actual slow query</span><br />
If slow logging is enabled, review its configured path through an administrator session. Logs can contain query text and user data: keep access restricted and do not upload raw logs to a public thread. A 3-second threshold will miss many shorter queries; choose a diagnostic threshold deliberately and monitor storage overhead.<br />
Find frequently repeated queries as well as individually expensive ones. Record execution count, latency and examined rows. A fast query executed thousands of times may still consume significant resources.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">3. Create a separate practice database</span><br />
Use a disposable database, never a production table, for this example. Our new database was af_performance_index_lab_20261014. In MariaDB 10.11, the sequence table below provides synthetic integers; this syntax is not a portable MySQL recipe.<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>CREATE DATABASE af_performance_index_lab_20261014;
USE af_performance_index_lab_20261014;
CREATE TABLE events (
  id INT PRIMARY KEY,
  account_id INT NOT NULL,
  status VARCHAR(16) NOT NULL,
  payload VARCHAR(100) NOT NULL
) ENGINE=InnoDB;
INSERT INTO events
SELECT seq, MOD(seq,1000),
       IF(MOD(seq,2)=0,'active','closed'), REPEAT('x',100)
FROM seq_1_to_50000;</code></div></div>Check that your chosen database name does not already exist. This example creates only synthetic data; adapt names and versions for your own isolated lab.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">4. Inspect the query plan before changing anything</span><br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>EXPLAIN SELECT SQL_NO_CACHE COUNT(*)
FROM events WHERE account_id=321 AND status='closed';</code></div></div>SQL_NO_CACHE is used here to exclude MariaDB's query-result cache; it does not empty the InnoDB buffer pool. Do not copy this clause into an incompatible database release.<br />
Our plan showed type ALL and an estimated 50,000 rows. EXPLAIN estimates are not measured execution counts, but this plan indicates a full table scan to evaluate the filters.<br />
The query returned 50 matching rows. Record the result so that a faster but incorrect rewrite is not accepted.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">5. Test a targeted composite index</span><br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>ALTER TABLE events
  ADD INDEX idx_account_status(account_id,status);
ANALYZE TABLE events;
EXPLAIN SELECT SQL_NO_CACHE COUNT(*)
FROM events WHERE account_id=321 AND status='closed';</code></div></div>The new plan used idx_account_status, type ref and an estimated 50 rows. It also reported Using index: this count query can be satisfied from the index entries needed for the filters.<br />
Index design depends on the actual predicates, sorting and joins. Column order matters for other queries using only part of a composite index. Avoid creating an index for every column: indexes use storage and add work to writes.<br />
On a large production table, building an index can consume time, space and locks. Check version-specific online DDL behavior, back up and plan the change before applying it to real data.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">6. Compare the same query</span><br />
We used MariaDB session profiling for this lab: one warmup followed by ten measured executions in each phase. The same database session setting and query were used before and after. Warm data remained possible in the buffer pool; this is not a cold-storage benchmark.<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>SET profiling=1;
SELECT SQL_NO_CACHE COUNT(*)
FROM events WHERE account_id=321 AND status='closed';
SHOW PROFILES;</code></div></div>Repeat the SELECT for your sample and inspect its reported duration. Session profiling is version-specific; use the diagnostic tools available in your actual database release. Disable temporary profiling when finished.<br />
<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=291" target="_blank" title="">database-index-comparison-20261014.jpg</a> (Size: 115.87 KB / Downloads: 5)
<!-- end: postbit_attachments_attachment --><br />
<span style="font-style: italic;" class="mycode_i">AdminsForum formatted transcript of the original lab test, not a terminal screenshot.</span><br />
<br />
The median of ten measured executions was about 12.72ms before and 0.188ms after. Both phases returned 50 rows. This supports this index for this synthetic query; it does not promise the same improvement for every website or establish production capacity.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">7. Tune resources only after reviewing evidence</span><br />
For InnoDB buffer sizing, account for the working data set and sustained physical reads, while reserving memory for PHP-FPM, Nginx, OS, mail and other services. Dedicated database-server percentage rules are unsuitable for every shared aaPanel VPS.<br />
For max_connections, inspect concurrent connections, application pooling and per-connection memory. Raising the limit can worsen overload. Our observed maximum of 3 did not justify increasing the limit of 200.<br />
Change one setting at a time, retain its original value, validate the database configuration and repeat representative workloads. Monitor swap, OOM events, errors and query latency. A restart can temporarily alter cache warmth and distort comparisons.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">8. Verify the website and retain a rollback plan</span><br />
Test real reads and writes, not just this SELECT. Compare execution plans and results, then monitor normal traffic. For our disposable table, the index can be removed with:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>ALTER TABLE events DROP INDEX idx_account_status;</code></div></div>Do not remove an existing production index without checking its other uses. We retained this isolated lab database and its index for repeatable demonstrations; no application database was modified.<br />
<br />
Continue with <a href="https://adminsforum.com/Thread-guide-tune-php-fpm-workers-in-aapanel-with-measured-memory-limits" target="_blank" rel="noopener" class="mycode_url">PHP-FPM memory limits</a> to balance the shared server, rather than tuning each service as though it owns all RAM.<br />
<br />
<br />
<span style="font-weight: bold;" class="mycode_b">References</span>: <a href="https://mariadb.com/docs/server/reference/sql-statements/administrative-sql-statements/analyze-and-explain-statements/explain" target="_blank" rel="noopener" class="mycode_url">MariaDB EXPLAIN</a> and <a href="https://mariadb.com/docs/server/reference/sql-statements/administrative-sql-statements/show/show-profiles" target="_blank" rel="noopener" class="mycode_url">SHOW PROFILES</a>.]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[Check MySQL Status and Error Logs in aaPanel]]></title>
			<link>https://adminsforum.com/Thread-guide-check-mysql-status-and-error-logs-in-aapanel</link>
			<pubDate>Tue, 13 Oct 2026 22:20:23 +0800</pubDate>
			<dc:creator><![CDATA[<a href="https://adminsforum.com/member.php?action=profile&uid=2">DEV</a>]]></dc:creator>
			<guid isPermaLink="false">https://adminsforum.com/Thread-guide-check-mysql-status-and-error-logs-in-aapanel</guid>
			<description><![CDATA[<span style="font-weight: bold;" class="mycode_b">When a website reports a database error, check the database service, connection settings and logs before restarting MySQL or changing passwords. aaPanel's MySQL manager can show the service controls, live status metrics and database error log in one place.</span><br />
<br />
This guide is for MySQL and MariaDB installations managed by aaPanel. A database problem is different from an Nginx or PHP-FPM problem: a working panel login does not prove that every website component is healthy.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">What we verified</span><br />
We inspected aaPanel 8.0.7 on our Ubuntu 22.04 lab on 13 October 2026. The software button was labelled mariadb_10.11.6, while the database startup log reported MariaDB 10.11.10. We also completed a SQL import and saw its two-row table in the database tools.<br />
<br />
The Service screen displayed <span style="font-weight: bold;" class="mycode_b">Current state: Stop</span>, yet Current status returned a launch time, connections and database statistics. This is a verified panel-status mismatch, not proof that MariaDB stopped. We did not restart or reinstall the database to make the label change, and we have not confirmed the underlying cause of that mismatch.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">1. Identify which layer is failing</span><br />
Record the exact error, affected website and time. Keep the message private if it contains a username, client IP or application path.<br />
<ul class="mycode_list"><li><span style="font-weight: bold;" class="mycode_b">A database connection error in the application:</span> check its database host, database name, username and password, as well as service availability.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">An import error:</span> use the Import dialog's Show Logs output. A failed SQL statement may leave a partially imported database.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">502 or 503 from the web server:</span> inspect the web server/PHP path too. Those HTTP errors do not, by themselves, identify a broken database.<br />
</li>
</ul>
Only one website failing while other database-backed websites work points toward a site-specific problem. All sites failing together makes the shared database service or VPS resources more relevant. Use these clues to narrow the checks; they are not a diagnosis on their own.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">2. Open the database service manager</span><br />
Go to <span style="font-weight: bold;" class="mycode_b">Databases → MySQL</span>, then click the installed service button above the database list. In our lab it was labelled <span style="font-weight: bold;" class="mycode_b">Mysql mariadb_10.11.6</span>. The same manager can also be reached through the installed MySQL/MariaDB app in App Store.<br />
<br />
Select <span style="font-weight: bold;" class="mycode_b">Service</span>. Read the state and available controls. Start, Restart and Reload are actions; do not click them merely to test whether the screen responds.<br />
<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=143" target="_blank" title="">mysql-state-mismatch-20261013.jpg</a> (Size: 178.89 KB / Downloads: 5)
<!-- end: postbit_attachments_attachment --><br />
<span style="font-style: italic;" class="mycode_i">Actual lab screen: the Service label says Stop. The next checks are essential before treating this label as the server's actual state.</span><br />
<br />
If the server is truly stopped, first collect the startup error and identify the reason. A restart can briefly interrupt every application using the service, and repeatedly restarting does not repair an invalid configuration, full disk or corrupted data.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">3. Cross-check Current status</span><br />
Open <span style="font-weight: bold;" class="mycode_b">Current status</span> in the manager. Wait for the figures to load. Note the launch time, connection totals and active connections. A momentary -- or NaN while the screen loads is not a final diagnostic result.<br />
<br />
Our screen returned real database metrics after loading, even though the Service tab's label remained Stop. Combined with the successful SQL import, this established that the database was responding to the panel at that time.<br />
<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=144" target="_blank" title="">mysql-live-status-20261013.jpg</a> (Size: 244.8 KB / Downloads: 5)
<!-- end: postbit_attachments_attachment --><br />
<span style="font-style: italic;" class="mycode_i">The lab's loaded status metrics. Counters and percentages vary with workload; they are not tuning targets to copy to another server.</span><br />
<br />
Do not increase every memory or cache setting because a panel tip suggests it. An apparently low hit rate can be irrelevant to your engine or workload. For a 4 GB VPS, raising several per-connection buffers can make memory pressure worse.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">4. Read Error log</span><br />
Select <span style="font-weight: bold;" class="mycode_b">Error log</span>. Read the most recent relevant lines and compare their timestamps with the failure time. Server and browser time zones can differ.<br />
<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=145" target="_blank" title="">mysql-error-log-view-20261013.jpg</a> (Size: 288.45 KB / Downloads: 4)
<!-- end: postbit_attachments_attachment --><br />
<span style="font-style: italic;" class="mycode_i">Our log contains startup information and a ready for connections message. That message is historical; the import and Current status checks provide the additional evidence that the lab is responding now.</span><br />
<br />
Pay attention to severity and context:<ul class="mycode_list"><li><span style="font-weight: bold;" class="mycode_b">Note:</span> often normal startup or background information. Our log's FEEDBACK plugin disabled note was not evidence of a stopped database.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Warning:</span> something to review, not automatically a fatal error. Our binary-log retention warning did not prevent the sample import.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Error:</span> investigate the named file, setting or resource and the lines immediately around it.<br />
</li>
</ul>
Do not use <span style="font-weight: bold;" class="mycode_b">Empty log</span> while diagnosing a failure. It removes useful evidence; it does not resolve the cause. Save a private copy of the relevant output before changing anything. Redact usernames, IP addresses, paths containing secrets and SQL data before posting screenshots for support.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">5. Distinguish a connection problem from a login problem</span><br />
The exact database-client error helps decide what to check next:<ul class="mycode_list"><li><span style="font-weight: bold;" class="mycode_b">2002 or 2003, cannot connect:</span> verify the service and the configured host, port or Unix socket. A running service may still be listening somewhere different from the client's settings.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">1045, access denied for user:</span> review the username, password and allowed host/account permissions. The root, aaPanel login and website database passwords are separate credentials.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">1044, access denied to a database:</span> check that the application account is permitted to use the requested database.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">1049, unknown database:</span> compare the configured database name with the database list and confirm that creation or migration completed.<br />
</li>
</ul>
These are general error interpretations from MariaDB's documentation. We did not reproduce each error or change credentials during this read-only walkthrough.<br />
<br />
For an application on the same VPS, opening MySQL port 3306 to everyone is not a fix for a wrong local password or database name. Likewise, changing the database root password is not a substitute for correcting a website's own connection settings.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">6. Optional checks through SSH</span><br />
If you already have working SSH access, these read-only checks can help corroborate a misleading panel label:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>/etc/init.d/mysqld status
ss -lntp | grep ':3306'
ls -lh /www/server/data/*.err</code></div></div>Use your actual port if it differs from 3306. An open listening port proves that a listener exists; it does not prove that the application can authenticate or query its tables.<br />
<br />
A test with the website's own database account is more specific:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>/www/server/mysql/bin/mysql --protocol=TCP   --host=127.0.0.1 --port=3306   --user=YOUR_DATABASE_USER --password   YOUR_DATABASE_NAME -e "SELECT 1;"</code></div></div>The --password option prompts interactively. Do not put a real password directly into a command that may be saved in shell history. This TCP test is different from a localhost Unix-socket connection; use the connection method your application actually requires. The optional SSH commands were not executed in this walkthrough because the lab's browser terminal was not connected.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">7. Change one confirmed cause, then verify the website</span><br />
Back up before a configuration change. Correct the specific failing setting rather than reinstalling the database or deleting files from its data directory. Retest the same connection and a real application page after the change.<br />
<br />
If the Service label and successful database queries disagree, report the evidence to aaPanel support: panel version, engine version from the server/log, state screenshot, Current status and the outcome of a harmless query. A hostname/PID-file or process-detection issue is a possibility to investigate, not a cause we have proved on this lab.<br />
<br />
Related guides:<br />
<a href="https://adminsforum.com/Thread-guide-import-a-sql-database-file-in-aapanel-step-by-step" target="_blank" rel="noopener" class="mycode_url">Import a SQL Database File in aaPanel</a><br />
<a href="https://adminsforum.com/Thread-guide-fix-502-bad-gateway-and-503-errors-in-aapanel" target="_blank" rel="noopener" class="mycode_url">Fix 502 Bad Gateway and 503 Errors in aaPanel</a><br />
<br />
References:<br />
<a href="https://www.aapanel.com/docs/Function/MySQL.html" target="_blank" rel="noopener" class="mycode_url">aaPanel MySQL manager</a><br />
<a href="https://www.aapanel.com/docs/faq/Service_Manage_Commands.html" target="_blank" rel="noopener" class="mycode_url">aaPanel service-management commands</a><br />
<a href="https://mariadb.com/docs/server/mariadb-quickstart-guides/mariadb-connection-troubleshooting-guide" target="_blank" rel="noopener" class="mycode_url">MariaDB connection troubleshooting</a>]]></description>
			<content:encoded><![CDATA[<span style="font-weight: bold;" class="mycode_b">When a website reports a database error, check the database service, connection settings and logs before restarting MySQL or changing passwords. aaPanel's MySQL manager can show the service controls, live status metrics and database error log in one place.</span><br />
<br />
This guide is for MySQL and MariaDB installations managed by aaPanel. A database problem is different from an Nginx or PHP-FPM problem: a working panel login does not prove that every website component is healthy.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">What we verified</span><br />
We inspected aaPanel 8.0.7 on our Ubuntu 22.04 lab on 13 October 2026. The software button was labelled mariadb_10.11.6, while the database startup log reported MariaDB 10.11.10. We also completed a SQL import and saw its two-row table in the database tools.<br />
<br />
The Service screen displayed <span style="font-weight: bold;" class="mycode_b">Current state: Stop</span>, yet Current status returned a launch time, connections and database statistics. This is a verified panel-status mismatch, not proof that MariaDB stopped. We did not restart or reinstall the database to make the label change, and we have not confirmed the underlying cause of that mismatch.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">1. Identify which layer is failing</span><br />
Record the exact error, affected website and time. Keep the message private if it contains a username, client IP or application path.<br />
<ul class="mycode_list"><li><span style="font-weight: bold;" class="mycode_b">A database connection error in the application:</span> check its database host, database name, username and password, as well as service availability.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">An import error:</span> use the Import dialog's Show Logs output. A failed SQL statement may leave a partially imported database.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">502 or 503 from the web server:</span> inspect the web server/PHP path too. Those HTTP errors do not, by themselves, identify a broken database.<br />
</li>
</ul>
Only one website failing while other database-backed websites work points toward a site-specific problem. All sites failing together makes the shared database service or VPS resources more relevant. Use these clues to narrow the checks; they are not a diagnosis on their own.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">2. Open the database service manager</span><br />
Go to <span style="font-weight: bold;" class="mycode_b">Databases → MySQL</span>, then click the installed service button above the database list. In our lab it was labelled <span style="font-weight: bold;" class="mycode_b">Mysql mariadb_10.11.6</span>. The same manager can also be reached through the installed MySQL/MariaDB app in App Store.<br />
<br />
Select <span style="font-weight: bold;" class="mycode_b">Service</span>. Read the state and available controls. Start, Restart and Reload are actions; do not click them merely to test whether the screen responds.<br />
<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=143" target="_blank" title="">mysql-state-mismatch-20261013.jpg</a> (Size: 178.89 KB / Downloads: 5)
<!-- end: postbit_attachments_attachment --><br />
<span style="font-style: italic;" class="mycode_i">Actual lab screen: the Service label says Stop. The next checks are essential before treating this label as the server's actual state.</span><br />
<br />
If the server is truly stopped, first collect the startup error and identify the reason. A restart can briefly interrupt every application using the service, and repeatedly restarting does not repair an invalid configuration, full disk or corrupted data.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">3. Cross-check Current status</span><br />
Open <span style="font-weight: bold;" class="mycode_b">Current status</span> in the manager. Wait for the figures to load. Note the launch time, connection totals and active connections. A momentary -- or NaN while the screen loads is not a final diagnostic result.<br />
<br />
Our screen returned real database metrics after loading, even though the Service tab's label remained Stop. Combined with the successful SQL import, this established that the database was responding to the panel at that time.<br />
<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=144" target="_blank" title="">mysql-live-status-20261013.jpg</a> (Size: 244.8 KB / Downloads: 5)
<!-- end: postbit_attachments_attachment --><br />
<span style="font-style: italic;" class="mycode_i">The lab's loaded status metrics. Counters and percentages vary with workload; they are not tuning targets to copy to another server.</span><br />
<br />
Do not increase every memory or cache setting because a panel tip suggests it. An apparently low hit rate can be irrelevant to your engine or workload. For a 4 GB VPS, raising several per-connection buffers can make memory pressure worse.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">4. Read Error log</span><br />
Select <span style="font-weight: bold;" class="mycode_b">Error log</span>. Read the most recent relevant lines and compare their timestamps with the failure time. Server and browser time zones can differ.<br />
<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=145" target="_blank" title="">mysql-error-log-view-20261013.jpg</a> (Size: 288.45 KB / Downloads: 4)
<!-- end: postbit_attachments_attachment --><br />
<span style="font-style: italic;" class="mycode_i">Our log contains startup information and a ready for connections message. That message is historical; the import and Current status checks provide the additional evidence that the lab is responding now.</span><br />
<br />
Pay attention to severity and context:<ul class="mycode_list"><li><span style="font-weight: bold;" class="mycode_b">Note:</span> often normal startup or background information. Our log's FEEDBACK plugin disabled note was not evidence of a stopped database.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Warning:</span> something to review, not automatically a fatal error. Our binary-log retention warning did not prevent the sample import.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Error:</span> investigate the named file, setting or resource and the lines immediately around it.<br />
</li>
</ul>
Do not use <span style="font-weight: bold;" class="mycode_b">Empty log</span> while diagnosing a failure. It removes useful evidence; it does not resolve the cause. Save a private copy of the relevant output before changing anything. Redact usernames, IP addresses, paths containing secrets and SQL data before posting screenshots for support.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">5. Distinguish a connection problem from a login problem</span><br />
The exact database-client error helps decide what to check next:<ul class="mycode_list"><li><span style="font-weight: bold;" class="mycode_b">2002 or 2003, cannot connect:</span> verify the service and the configured host, port or Unix socket. A running service may still be listening somewhere different from the client's settings.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">1045, access denied for user:</span> review the username, password and allowed host/account permissions. The root, aaPanel login and website database passwords are separate credentials.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">1044, access denied to a database:</span> check that the application account is permitted to use the requested database.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">1049, unknown database:</span> compare the configured database name with the database list and confirm that creation or migration completed.<br />
</li>
</ul>
These are general error interpretations from MariaDB's documentation. We did not reproduce each error or change credentials during this read-only walkthrough.<br />
<br />
For an application on the same VPS, opening MySQL port 3306 to everyone is not a fix for a wrong local password or database name. Likewise, changing the database root password is not a substitute for correcting a website's own connection settings.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">6. Optional checks through SSH</span><br />
If you already have working SSH access, these read-only checks can help corroborate a misleading panel label:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>/etc/init.d/mysqld status
ss -lntp | grep ':3306'
ls -lh /www/server/data/*.err</code></div></div>Use your actual port if it differs from 3306. An open listening port proves that a listener exists; it does not prove that the application can authenticate or query its tables.<br />
<br />
A test with the website's own database account is more specific:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>/www/server/mysql/bin/mysql --protocol=TCP   --host=127.0.0.1 --port=3306   --user=YOUR_DATABASE_USER --password   YOUR_DATABASE_NAME -e "SELECT 1;"</code></div></div>The --password option prompts interactively. Do not put a real password directly into a command that may be saved in shell history. This TCP test is different from a localhost Unix-socket connection; use the connection method your application actually requires. The optional SSH commands were not executed in this walkthrough because the lab's browser terminal was not connected.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">7. Change one confirmed cause, then verify the website</span><br />
Back up before a configuration change. Correct the specific failing setting rather than reinstalling the database or deleting files from its data directory. Retest the same connection and a real application page after the change.<br />
<br />
If the Service label and successful database queries disagree, report the evidence to aaPanel support: panel version, engine version from the server/log, state screenshot, Current status and the outcome of a harmless query. A hostname/PID-file or process-detection issue is a possibility to investigate, not a cause we have proved on this lab.<br />
<br />
Related guides:<br />
<a href="https://adminsforum.com/Thread-guide-import-a-sql-database-file-in-aapanel-step-by-step" target="_blank" rel="noopener" class="mycode_url">Import a SQL Database File in aaPanel</a><br />
<a href="https://adminsforum.com/Thread-guide-fix-502-bad-gateway-and-503-errors-in-aapanel" target="_blank" rel="noopener" class="mycode_url">Fix 502 Bad Gateway and 503 Errors in aaPanel</a><br />
<br />
References:<br />
<a href="https://www.aapanel.com/docs/Function/MySQL.html" target="_blank" rel="noopener" class="mycode_url">aaPanel MySQL manager</a><br />
<a href="https://www.aapanel.com/docs/faq/Service_Manage_Commands.html" target="_blank" rel="noopener" class="mycode_url">aaPanel service-management commands</a><br />
<a href="https://mariadb.com/docs/server/mariadb-quickstart-guides/mariadb-connection-troubleshooting-guide" target="_blank" rel="noopener" class="mycode_url">MariaDB connection troubleshooting</a>]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[Import a SQL Database File in aaPanel (Step by Step)]]></title>
			<link>https://adminsforum.com/Thread-guide-import-a-sql-database-file-in-aapanel-step-by-step</link>
			<pubDate>Tue, 13 Oct 2026 22:08:05 +0800</pubDate>
			<dc:creator><![CDATA[<a href="https://adminsforum.com/member.php?action=profile&uid=2">DEV</a>]]></dc:creator>
			<guid isPermaLink="false">https://adminsforum.com/Thread-guide-import-a-sql-database-file-in-aapanel-step-by-step</guid>
			<description><![CDATA[<span style="font-weight: bold;" class="mycode_b">To import a MySQL or MariaDB database in aaPanel, open Databases, choose Import beside the correct database, upload your SQL file and confirm the import. Back up first, then verify the imported tables and data.</span><br />
<br />
This walkthrough uses aaPanel's built-in importer. You do not need to expose phpMyAdmin publicly or open MySQL port 3306 to the internet.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Tested lab</span><br />
Ubuntu 22.04 and aaPanel 8.0.7, tested on 13 October 2026. The database startup log reports MariaDB 10.11.10; the panel software button still displays the mariadb_10.11.6 label. The destination was our isolated adminsforum_lab tutorial database. We created a fresh backup, imported one sample table and verified that the panel lists it with a Row number of 2. The existing af_backup_check table remained present with one row. We did not import into the WordPress or webmail databases.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Before you begin</span><ul class="mycode_list"><li>A running MySQL or MariaDB service and a database created in aaPanel.<br />
</li>
<li>A trusted .sql export containing database structure and/or data, not website files.<br />
</li>
<li>Enough free disk space for the upload, extracted archive and database.<br />
</li>
<li>A current backup of anything already in the destination database.<br />
</li>
</ul>
For a migration, start with a separate empty destination database. A SQL dump can contain DROP TABLE, DELETE, TRUNCATE or USE statements. aaPanel warns that an import may overwrite the selected database. Do not test an unfamiliar file against a working website database.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">1. Choose the destination and create a backup</span><br />
Open <span style="font-weight: bold;" class="mycode_b">Databases → MySQL</span>. The MySQL tab also manages our installed MariaDB service. Read the database name carefully; it is not always the same as the website domain.<br />
<br />
If the database does not exist, follow <a href="https://adminsforum.com/Thread-guide-create-a-database-and-user-in-aapanel-free-edition" target="_blank" rel="noopener" class="mycode_url">Create a Database and User in aaPanel</a> first. Use a separate database rather than importing over another site's tables.<br />
<br />
In the destination row, click its <span style="font-weight: bold;" class="mycode_b">Backup</span> value, such as Exists(1), to open the backup details. Click <span style="font-weight: bold;" class="mycode_b">Backup</span>, wait for the background task to finish and confirm that a new dated archive appears with a non-zero size. Keep a private copy off the VPS for important data. Do not post a real SQL dump or its passwords in a support thread.<br />
<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=139" target="_blank" title="">sql-import-backup-20261013.jpg</a> (Size: 52.91 KB / Downloads: 8)
<!-- end: postbit_attachments_attachment --><br />
<span style="font-style: italic;" class="mycode_i">Our pre-import backup appeared in the list before we continued. Backup creation alone is not a tested restore.</span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">2. Check the file before uploading</span><br />
Use the SQL export from the source database or a harmless sample for practice. A renamed spreadsheet, HTML error page or ZIP without a SQL file is not a database export.<br />
<br />
For this rehearsal, our file was plain SQL. It created a uniquely named training table and inserted two rows:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>CREATE TABLE IF NOT EXISTS af_import_lesson_20261013 (
  id INT NOT NULL PRIMARY KEY,
  title VARCHAR(120) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

INSERT INTO af_import_lesson_20261013 (id, title) VALUES
  (1, 'Welcome to AdminsForum'),
  (2, 'SQL import verified')
ON DUPLICATE KEY UPDATE title=VALUES(title);</code></div></div>Save this as a UTF-8 file ending in .sql if you want to practise in your own empty lab database. This is demonstration data, not a WordPress migration file. It contains no DROP, DELETE or USE statement.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">3. Open Import beside the correct database</span><br />
Return to the database list and click <span style="font-weight: bold;" class="mycode_b">Import</span> in your destination row. Check the database name in the dialog title before selecting a file.<br />
<br />
The dialog lists database archives stored on the server. <span style="font-weight: bold;" class="mycode_b">Do not choose an unrelated backup simply because it appears in the list.</span> The list can contain backups from other databases, including WordPress.<br />
<br />
Click <span style="font-weight: bold;" class="mycode_b">Upload from local → Select file</span>, choose your .sql file and click <span style="font-weight: bold;" class="mycode_b">Upload</span>. Wait for the upload to finish. Uploading only transfers the file; it does not yet execute the SQL.<br />
<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=140" target="_blank" title="">sql-import-upload-20261013.jpg</a> (Size: 62.43 KB / Downloads: 6)
<!-- end: postbit_attachments_attachment --><br />
<span style="font-style: italic;" class="mycode_i">The sample file is selected in the upload dialog. Complete the upload before starting Import.</span><br />
<br />
The tested panel lists .sql, .zip, .gz, .tar.gz and .tgz support. When using an archive, check that it actually contains the intended SQL dump. For a file too large for browser upload, aaPanel's dialog suggests SFTP upload to /www/backup/database. Keep database backups outside the public website directory.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">4. Start the import and read the warning</span><br />
After upload, find the exact filename in the import list and click <span style="font-weight: bold;" class="mycode_b">Import</span> on that row. aaPanel asks: <span style="font-weight: bold;" class="mycode_b">Database will be overwritten, continue?</span><br />
<br />
Only confirm after checking the destination database, selected file and backup. Wait while aaPanel runs the background import. Avoid repeated clicks or starting several imports into the same database.<br />
<br />
Closing the progress window is not evidence of success. The panel says the task continues in the background; use the log to check its result.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">5. Read the import log</span><br />
In the import dialog, click <span style="font-weight: bold;" class="mycode_b">Show Logs</span> and refresh if necessary. Read the output for the correct database and for errors. Our log reported <span style="font-weight: bold;" class="mycode_b">Import status: Successful</span> and <span style="font-weight: bold;" class="mycode_b">Database recovery successful!</span><br />
<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=141" target="_blank" title="">sql-import-success-20261013.jpg</a> (Size: 65.11 KB / Downloads: 7)
<!-- end: postbit_attachments_attachment --><br />
<span style="font-style: italic;" class="mycode_i">Actual log from the two-row lab import. A tiny sample completing quickly is not a speed estimate for large website databases.</span><br />
<br />
If the log reports a SQL error, the database may already contain partially imported tables. Investigate that error before repeating the import. Do not assume a retry automatically undoes earlier statements.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">6. Verify the tables and rows</span><br />
Close the import dialog and open <span style="font-weight: bold;" class="mycode_b">Tools</span> in the destination database row. Confirm that the expected table names appear. Our new af_import_lesson_20261013 table showed two rows, and the old backup-test table was still present.<br />
<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=142" target="_blank" title="">sql-import-table-check-20261013.jpg</a> (Size: 71.83 KB / Downloads: 8)
<!-- end: postbit_attachments_attachment --><br />
<span style="font-style: italic;" class="mycode_i">The new training table and the original test table are both visible. We only inspected this screen; Repair, Optimize and engine conversion were not needed.</span><br />
<br />
For an exact data check, use your private database client or phpMyAdmin to run:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>SELECT COUNT(*) AS imported_rows
FROM af_import_lesson_20261013;

SELECT id, title
FROM af_import_lesson_20261013
ORDER BY id;</code></div></div>For this sample, expect two rows and the two titles above. The screenshot's table row number is a useful panel check; use SELECT to verify exact counts for a real migration.<br />
<br />
For a website migration, also update the application's database settings to the new database, check a real page and test any login or form that depends on it. Imported tables alone do not prove that the application is configured correctly.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Troubleshooting</span><ul class="mycode_list"><li><span style="font-weight: bold;" class="mycode_b">The file is missing from the list:</span> finish the upload, reopen Import and check the filename. An uploaded file and an imported database are separate steps.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Unknown collation or SQL syntax error:</span> compare the source and destination database versions. Request a compatible export or review the failing SQL. Do not blindly replace every collation name in a production dump.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Access denied:</span> check the database service and aaPanel's stored database credentials. Opening port 3306 to everyone does not fix a local importer authentication error.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Table already exists or duplicate entry:</span> check whether you selected a populated destination or already ran the file. For a migration, use a separate empty database and retain the original backup.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Success message but missing data:</span> check the selected database, expected table prefix and actual row contents. A structure-only export can create tables without restoring records.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Large import stalls or fails:</span> inspect the log, available disk space and archive contents. Do not change PHP upload limits at random; browser upload and the panel's background database import are different stages.<br />
</li>
</ul>
<br />
<span style="font-weight: bold;" class="mycode_b">Rollback and next steps</span><br />
If an import damages existing data, stop changes and restore the correct pre-import backup through the database backup controls. Validate a restore in an isolated database before making a live application depend on it. See <a href="https://adminsforum.com/Thread-guide-back-up-and-restore-a-database-in-aapanel-free-edition" target="_blank" rel="noopener" class="mycode_url">Back Up and Restore a Database in aaPanel</a> for the recovery workflow.<br />
<br />
<a href="https://www.aapanel.com/docs/Function/MySQL.html" target="_blank" rel="noopener" class="mycode_url">aaPanel MySQL database documentation</a><br />
<br />
<a href="https://adminsforum.com/Thread-guide-check-mysql-status-and-error-logs-in-aapanel" target="_blank" rel="noopener" class="mycode_url">Check MySQL Status and Error Logs in aaPanel</a>]]></description>
			<content:encoded><![CDATA[<span style="font-weight: bold;" class="mycode_b">To import a MySQL or MariaDB database in aaPanel, open Databases, choose Import beside the correct database, upload your SQL file and confirm the import. Back up first, then verify the imported tables and data.</span><br />
<br />
This walkthrough uses aaPanel's built-in importer. You do not need to expose phpMyAdmin publicly or open MySQL port 3306 to the internet.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Tested lab</span><br />
Ubuntu 22.04 and aaPanel 8.0.7, tested on 13 October 2026. The database startup log reports MariaDB 10.11.10; the panel software button still displays the mariadb_10.11.6 label. The destination was our isolated adminsforum_lab tutorial database. We created a fresh backup, imported one sample table and verified that the panel lists it with a Row number of 2. The existing af_backup_check table remained present with one row. We did not import into the WordPress or webmail databases.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Before you begin</span><ul class="mycode_list"><li>A running MySQL or MariaDB service and a database created in aaPanel.<br />
</li>
<li>A trusted .sql export containing database structure and/or data, not website files.<br />
</li>
<li>Enough free disk space for the upload, extracted archive and database.<br />
</li>
<li>A current backup of anything already in the destination database.<br />
</li>
</ul>
For a migration, start with a separate empty destination database. A SQL dump can contain DROP TABLE, DELETE, TRUNCATE or USE statements. aaPanel warns that an import may overwrite the selected database. Do not test an unfamiliar file against a working website database.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">1. Choose the destination and create a backup</span><br />
Open <span style="font-weight: bold;" class="mycode_b">Databases → MySQL</span>. The MySQL tab also manages our installed MariaDB service. Read the database name carefully; it is not always the same as the website domain.<br />
<br />
If the database does not exist, follow <a href="https://adminsforum.com/Thread-guide-create-a-database-and-user-in-aapanel-free-edition" target="_blank" rel="noopener" class="mycode_url">Create a Database and User in aaPanel</a> first. Use a separate database rather than importing over another site's tables.<br />
<br />
In the destination row, click its <span style="font-weight: bold;" class="mycode_b">Backup</span> value, such as Exists(1), to open the backup details. Click <span style="font-weight: bold;" class="mycode_b">Backup</span>, wait for the background task to finish and confirm that a new dated archive appears with a non-zero size. Keep a private copy off the VPS for important data. Do not post a real SQL dump or its passwords in a support thread.<br />
<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=139" target="_blank" title="">sql-import-backup-20261013.jpg</a> (Size: 52.91 KB / Downloads: 8)
<!-- end: postbit_attachments_attachment --><br />
<span style="font-style: italic;" class="mycode_i">Our pre-import backup appeared in the list before we continued. Backup creation alone is not a tested restore.</span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">2. Check the file before uploading</span><br />
Use the SQL export from the source database or a harmless sample for practice. A renamed spreadsheet, HTML error page or ZIP without a SQL file is not a database export.<br />
<br />
For this rehearsal, our file was plain SQL. It created a uniquely named training table and inserted two rows:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>CREATE TABLE IF NOT EXISTS af_import_lesson_20261013 (
  id INT NOT NULL PRIMARY KEY,
  title VARCHAR(120) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

INSERT INTO af_import_lesson_20261013 (id, title) VALUES
  (1, 'Welcome to AdminsForum'),
  (2, 'SQL import verified')
ON DUPLICATE KEY UPDATE title=VALUES(title);</code></div></div>Save this as a UTF-8 file ending in .sql if you want to practise in your own empty lab database. This is demonstration data, not a WordPress migration file. It contains no DROP, DELETE or USE statement.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">3. Open Import beside the correct database</span><br />
Return to the database list and click <span style="font-weight: bold;" class="mycode_b">Import</span> in your destination row. Check the database name in the dialog title before selecting a file.<br />
<br />
The dialog lists database archives stored on the server. <span style="font-weight: bold;" class="mycode_b">Do not choose an unrelated backup simply because it appears in the list.</span> The list can contain backups from other databases, including WordPress.<br />
<br />
Click <span style="font-weight: bold;" class="mycode_b">Upload from local → Select file</span>, choose your .sql file and click <span style="font-weight: bold;" class="mycode_b">Upload</span>. Wait for the upload to finish. Uploading only transfers the file; it does not yet execute the SQL.<br />
<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=140" target="_blank" title="">sql-import-upload-20261013.jpg</a> (Size: 62.43 KB / Downloads: 6)
<!-- end: postbit_attachments_attachment --><br />
<span style="font-style: italic;" class="mycode_i">The sample file is selected in the upload dialog. Complete the upload before starting Import.</span><br />
<br />
The tested panel lists .sql, .zip, .gz, .tar.gz and .tgz support. When using an archive, check that it actually contains the intended SQL dump. For a file too large for browser upload, aaPanel's dialog suggests SFTP upload to /www/backup/database. Keep database backups outside the public website directory.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">4. Start the import and read the warning</span><br />
After upload, find the exact filename in the import list and click <span style="font-weight: bold;" class="mycode_b">Import</span> on that row. aaPanel asks: <span style="font-weight: bold;" class="mycode_b">Database will be overwritten, continue?</span><br />
<br />
Only confirm after checking the destination database, selected file and backup. Wait while aaPanel runs the background import. Avoid repeated clicks or starting several imports into the same database.<br />
<br />
Closing the progress window is not evidence of success. The panel says the task continues in the background; use the log to check its result.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">5. Read the import log</span><br />
In the import dialog, click <span style="font-weight: bold;" class="mycode_b">Show Logs</span> and refresh if necessary. Read the output for the correct database and for errors. Our log reported <span style="font-weight: bold;" class="mycode_b">Import status: Successful</span> and <span style="font-weight: bold;" class="mycode_b">Database recovery successful!</span><br />
<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=141" target="_blank" title="">sql-import-success-20261013.jpg</a> (Size: 65.11 KB / Downloads: 7)
<!-- end: postbit_attachments_attachment --><br />
<span style="font-style: italic;" class="mycode_i">Actual log from the two-row lab import. A tiny sample completing quickly is not a speed estimate for large website databases.</span><br />
<br />
If the log reports a SQL error, the database may already contain partially imported tables. Investigate that error before repeating the import. Do not assume a retry automatically undoes earlier statements.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">6. Verify the tables and rows</span><br />
Close the import dialog and open <span style="font-weight: bold;" class="mycode_b">Tools</span> in the destination database row. Confirm that the expected table names appear. Our new af_import_lesson_20261013 table showed two rows, and the old backup-test table was still present.<br />
<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=142" target="_blank" title="">sql-import-table-check-20261013.jpg</a> (Size: 71.83 KB / Downloads: 8)
<!-- end: postbit_attachments_attachment --><br />
<span style="font-style: italic;" class="mycode_i">The new training table and the original test table are both visible. We only inspected this screen; Repair, Optimize and engine conversion were not needed.</span><br />
<br />
For an exact data check, use your private database client or phpMyAdmin to run:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>SELECT COUNT(*) AS imported_rows
FROM af_import_lesson_20261013;

SELECT id, title
FROM af_import_lesson_20261013
ORDER BY id;</code></div></div>For this sample, expect two rows and the two titles above. The screenshot's table row number is a useful panel check; use SELECT to verify exact counts for a real migration.<br />
<br />
For a website migration, also update the application's database settings to the new database, check a real page and test any login or form that depends on it. Imported tables alone do not prove that the application is configured correctly.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Troubleshooting</span><ul class="mycode_list"><li><span style="font-weight: bold;" class="mycode_b">The file is missing from the list:</span> finish the upload, reopen Import and check the filename. An uploaded file and an imported database are separate steps.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Unknown collation or SQL syntax error:</span> compare the source and destination database versions. Request a compatible export or review the failing SQL. Do not blindly replace every collation name in a production dump.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Access denied:</span> check the database service and aaPanel's stored database credentials. Opening port 3306 to everyone does not fix a local importer authentication error.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Table already exists or duplicate entry:</span> check whether you selected a populated destination or already ran the file. For a migration, use a separate empty database and retain the original backup.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Success message but missing data:</span> check the selected database, expected table prefix and actual row contents. A structure-only export can create tables without restoring records.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Large import stalls or fails:</span> inspect the log, available disk space and archive contents. Do not change PHP upload limits at random; browser upload and the panel's background database import are different stages.<br />
</li>
</ul>
<br />
<span style="font-weight: bold;" class="mycode_b">Rollback and next steps</span><br />
If an import damages existing data, stop changes and restore the correct pre-import backup through the database backup controls. Validate a restore in an isolated database before making a live application depend on it. See <a href="https://adminsforum.com/Thread-guide-back-up-and-restore-a-database-in-aapanel-free-edition" target="_blank" rel="noopener" class="mycode_url">Back Up and Restore a Database in aaPanel</a> for the recovery workflow.<br />
<br />
<a href="https://www.aapanel.com/docs/Function/MySQL.html" target="_blank" rel="noopener" class="mycode_url">aaPanel MySQL database documentation</a><br />
<br />
<a href="https://adminsforum.com/Thread-guide-check-mysql-status-and-error-logs-in-aapanel" target="_blank" rel="noopener" class="mycode_url">Check MySQL Status and Error Logs in aaPanel</a>]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[Create a Database and User in aaPanel Free Edition]]></title>
			<link>https://adminsforum.com/Thread-guide-create-a-database-and-user-in-aapanel-free-edition</link>
			<pubDate>Sun, 11 Oct 2026 02:33:33 +0800</pubDate>
			<dc:creator><![CDATA[<a href="https://adminsforum.com/member.php?action=profile&uid=2">DEV</a>]]></dc:creator>
			<guid isPermaLink="false">https://adminsforum.com/Thread-guide-create-a-database-and-user-in-aapanel-free-edition</guid>
			<description><![CDATA[<span style="font-weight: bold;" class="mycode_b">Quick answer</span><br />
Open Databases &gt; MySQL &gt; Add DB in aaPanel Free Edition. Enter a database name and a separate application user, keep utf8mb4, generate a strong password, and use Local server permission when the application runs on this VPS. Save, then verify the database appears in the list.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Before you start</span><br />
MariaDB or MySQL must already be installed and running. aaPanel's MySQL tab also manages our MariaDB installation. Our lab website is created, but it does not yet have an application connected to this database.<br />
<a href="https://adminsforum.com/Thread-guide-install-mariadb-in-aapanel-free-edition" target="_blank" rel="noopener" class="mycode_url">Install MariaDB first</a>.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">1. Open Add DB</span><br />
In the left menu, select Databases, then the MySQL tab and Add DB. Do not change the Root password for ordinary website setup.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">2. Choose the database and user</span><br />
Our example uses:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>Database name: adminsforum_lab
Database user: adminsforum_lab
Character set: utf8mb4</code></div></div>Use a short, clear name for your own application. Keep a dedicated user for each database rather than connecting a website as root. utf8mb4 supports full Unicode, including emoji; check your application's requirements if it specifies a different character set.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">3. Set the password and access</span><br />
Generate a long, unique password and store it privately for the application's configuration. Never copy a tutorial password into a live website.<br />
Choose Local server when the application and database are on this same VPS. The Add to field should identify LocalServer (127.0.0.1). Do not choose access from everyone or open port 3306 just to run a local website.<br />
Click Confirm and wait for completion.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">4. Verify the database list</span><br />
Check the database name, username and Localhost location. Keep the password masked when sharing screenshots. Our verified result is shown below:<br />
<br />
<img src="https://adminsforum.com/attachment.php?aid=15" loading="lazy"  alt="[Image: attachment.php?aid=15]" class="mycode_img" /><br />
<br />
Our lab database was created through aaPanel's server-side database manager and then checked in the dashboard. A local connection using its dedicated user successfully selected adminsforum_lab. The user has privileges on that application database; we did not enable remote database access.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">5. Use the details in your application</span><br />
A typical same-server application needs:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>Database host: localhost or 127.0.0.1 (follow the application requirements)
Database port: 3306
Database name: your database name
Database user: your application user
Database password: your private generated password</code></div></div>localhost can use a Unix socket while 127.0.0.1 uses TCP; use the connection method your application and database configuration support. This guide verifies the database account, not a completed CMS installation.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Troubleshooting</span><br />
<span style="font-weight: bold;" class="mycode_b">Access denied:</span> Check the username, password and allowed host. Do not solve it by using root.<br />
<span style="font-weight: bold;" class="mycode_b">Unknown database:</span> Check the exact database name in the panel.<br />
<span style="font-weight: bold;" class="mycode_b">Connection refused:</span> Check that MariaDB/MySQL is running and listening for the connection method you selected.<br />
<span style="font-weight: bold;" class="mycode_b">No database in the list:</span> Read the creation error before retrying; avoid creating several accounts blindly.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Next steps</span><br />
Configure your website application with these credentials, then back up the database before importing data or making major changes. Website files and database backups are separate: both matter for a working restore.<br />
<a href="https://adminsforum.com/Thread-guide-create-a-website-in-aapanel-free-edition" target="_blank" rel="noopener" class="mycode_url">Create a website in aaPanel Free Edition</a><br />
<br />
<span style="font-weight: bold;" class="mycode_b">Tested:</span> 10 October 2026, aaPanel Free Edition 8.0.6 with MariaDB on Ubuntu 22.04. Original AdminsForum lab screenshot, with the database password masked.<br /><!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=15" target="_blank" title="">database-created-20261010.jpg</a> (Size: 44.79 KB / Downloads: 10)
<!-- end: postbit_attachments_attachment -->]]></description>
			<content:encoded><![CDATA[<span style="font-weight: bold;" class="mycode_b">Quick answer</span><br />
Open Databases &gt; MySQL &gt; Add DB in aaPanel Free Edition. Enter a database name and a separate application user, keep utf8mb4, generate a strong password, and use Local server permission when the application runs on this VPS. Save, then verify the database appears in the list.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Before you start</span><br />
MariaDB or MySQL must already be installed and running. aaPanel's MySQL tab also manages our MariaDB installation. Our lab website is created, but it does not yet have an application connected to this database.<br />
<a href="https://adminsforum.com/Thread-guide-install-mariadb-in-aapanel-free-edition" target="_blank" rel="noopener" class="mycode_url">Install MariaDB first</a>.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">1. Open Add DB</span><br />
In the left menu, select Databases, then the MySQL tab and Add DB. Do not change the Root password for ordinary website setup.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">2. Choose the database and user</span><br />
Our example uses:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>Database name: adminsforum_lab
Database user: adminsforum_lab
Character set: utf8mb4</code></div></div>Use a short, clear name for your own application. Keep a dedicated user for each database rather than connecting a website as root. utf8mb4 supports full Unicode, including emoji; check your application's requirements if it specifies a different character set.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">3. Set the password and access</span><br />
Generate a long, unique password and store it privately for the application's configuration. Never copy a tutorial password into a live website.<br />
Choose Local server when the application and database are on this same VPS. The Add to field should identify LocalServer (127.0.0.1). Do not choose access from everyone or open port 3306 just to run a local website.<br />
Click Confirm and wait for completion.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">4. Verify the database list</span><br />
Check the database name, username and Localhost location. Keep the password masked when sharing screenshots. Our verified result is shown below:<br />
<br />
<img src="https://adminsforum.com/attachment.php?aid=15" loading="lazy"  alt="[Image: attachment.php?aid=15]" class="mycode_img" /><br />
<br />
Our lab database was created through aaPanel's server-side database manager and then checked in the dashboard. A local connection using its dedicated user successfully selected adminsforum_lab. The user has privileges on that application database; we did not enable remote database access.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">5. Use the details in your application</span><br />
A typical same-server application needs:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>Database host: localhost or 127.0.0.1 (follow the application requirements)
Database port: 3306
Database name: your database name
Database user: your application user
Database password: your private generated password</code></div></div>localhost can use a Unix socket while 127.0.0.1 uses TCP; use the connection method your application and database configuration support. This guide verifies the database account, not a completed CMS installation.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Troubleshooting</span><br />
<span style="font-weight: bold;" class="mycode_b">Access denied:</span> Check the username, password and allowed host. Do not solve it by using root.<br />
<span style="font-weight: bold;" class="mycode_b">Unknown database:</span> Check the exact database name in the panel.<br />
<span style="font-weight: bold;" class="mycode_b">Connection refused:</span> Check that MariaDB/MySQL is running and listening for the connection method you selected.<br />
<span style="font-weight: bold;" class="mycode_b">No database in the list:</span> Read the creation error before retrying; avoid creating several accounts blindly.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Next steps</span><br />
Configure your website application with these credentials, then back up the database before importing data or making major changes. Website files and database backups are separate: both matter for a working restore.<br />
<a href="https://adminsforum.com/Thread-guide-create-a-website-in-aapanel-free-edition" target="_blank" rel="noopener" class="mycode_url">Create a website in aaPanel Free Edition</a><br />
<br />
<span style="font-weight: bold;" class="mycode_b">Tested:</span> 10 October 2026, aaPanel Free Edition 8.0.6 with MariaDB on Ubuntu 22.04. Original AdminsForum lab screenshot, with the database password masked.<br /><!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=15" target="_blank" title="">database-created-20261010.jpg</a> (Size: 44.79 KB / Downloads: 10)
<!-- end: postbit_attachments_attachment -->]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[Install phpMyAdmin in aaPanel Free Edition]]></title>
			<link>https://adminsforum.com/Thread-guide-install-phpmyadmin-in-aapanel-free-edition</link>
			<pubDate>Sat, 10 Oct 2026 23:29:03 +0800</pubDate>
			<dc:creator><![CDATA[<a href="https://adminsforum.com/member.php?action=profile&uid=2">DEV</a>]]></dc:creator>
			<guid isPermaLink="false">https://adminsforum.com/Thread-guide-install-phpmyadmin-in-aapanel-free-edition</guid>
			<description><![CDATA[<span style="font-weight: bold;" class="mycode_b">phpMyAdmin is a browser tool for working with MySQL or MariaDB databases. In this beginner guide, you will learn how to find its aaPanel installation, check its PHP runtime, understand its access settings, and prepare the correct database login.</span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">Lab verification:</span> Ubuntu 22.04.5, aaPanel Free Edition 8.0.6, phpMyAdmin 5.2 and MariaDB. Installation was completed with our original stack; management screens were checked again on 11 October 2026. phpMyAdmin uses PHP-84 while our website uses PHP 8.5. The panel's private launch currently requests an aaPanel vendor account login. Database browsing, import and export are not yet verified through that browser route.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Before you start: understand the three components</span></span><ul class="mycode_list"><li><span style="font-weight: bold;" class="mycode_b">MariaDB/MySQL:</span> The database server that stores your site's data.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">PHP:</span> The runtime that executes phpMyAdmin and PHP applications.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">phpMyAdmin:</span> A graphical tool that connects to the database server. It does not replace that server.<br />
</li>
</ul>
A website can use its database without phpMyAdmin being installed. Installing phpMyAdmin also does not create a WordPress database or a database user automatically.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">You need:</span> Access to your aaPanel, an installed database server, a compatible installed PHP runtime, and a database/user if you want to administer application data. Use a test database for practice. Back up an existing database before changing its contents.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Step 1 — Find phpMyAdmin in the App Store</span></span><br />
1. Sign in to your own aaPanel.<br />
2. Click <span style="font-weight: bold;" class="mycode_b">App Store</span> in the left menu.<br />
3. Enter <span style="font-weight: bold;" class="mycode_b">phpMyAdmin</span> in the app search field and submit the search.<br />
4. Locate the official phpMyAdmin row.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">What you should see:</span> Our lab shows <span style="font-weight: bold;" class="mycode_b">phpMyAdmin 5.2</span>, price <span style="font-weight: bold;" class="mycode_b">Free</span>, and <span style="font-weight: bold;" class="mycode_b">Setting</span> and <span style="font-weight: bold;" class="mycode_b">Uninstall</span> actions. These actions indicate that it is already installed. Do not uninstall it just to follow an installation guide.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">AdminsForum lab screenshot — the installed app entry</span><br />
<img src="https://adminsforum.com/uploads/tutorials/phpmyadmin-app-entry-branded-20261011.png" loading="lazy"  alt="[Image: phpmyadmin-app-entry-branded-20261011.png]" class="mycode_img" /><br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Step 2 — Install only if the app is missing</span></span><br />
If your row offers <span style="font-weight: bold;" class="mycode_b">Install</span>, select it, follow the panel's installation dialog, and wait until the task reports completion. Do not close or repeat the installation while its task is still running. Return to the app search and confirm that <span style="font-weight: bold;" class="mycode_b">Setting</span> is available.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Why this check matters:</span> Starting a task is not the same as completing it. If installation fails, record the actual message and inspect the task log before trying again. The screenshot above shows the completed installation state; it does not show a fresh installation dialog.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Step 3 — Check the PHP runtime used by phpMyAdmin</span></span><br />
1. Click <span style="font-weight: bold;" class="mycode_b">Setting</span> on the phpMyAdmin row.<br />
2. Select <span style="font-weight: bold;" class="mycode_b">PHP version</span> in the management window.<br />
3. Read the currently selected runtime.<br />
4. If it is already a suitable installed PHP version, leave it unchanged.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">What you should see:</span> Our selection is <span style="font-weight: bold;" class="mycode_b">PHP-84</span>, meaning PHP 8.4. The screenshot also offers PHP-85. This guide does not switch phpMyAdmin to 8.5 or claim that this switch was tested.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">AdminsForum lab screenshot — phpMyAdmin's own PHP selection</span><br />
<img src="https://adminsforum.com/uploads/tutorials/phpmyadmin-runtime-detail-branded-20261011.png" loading="lazy"  alt="[Image: phpmyadmin-runtime-detail-branded-20261011.png]" class="mycode_img" /><br />
<br />
<span style="font-weight: bold;" class="mycode_b">Why this matters:</span> The website PHP selection and phpMyAdmin PHP selection are separate. Changing your website to PHP 8.5 does not mean phpMyAdmin must use 8.5. <span style="font-weight: bold;" class="mycode_b">Static</span> is not an appropriate runtime for a PHP application. If you deliberately change this selection, choose an installed compatible runtime, click <span style="font-weight: bold;" class="mycode_b">Save</span>, and test opening phpMyAdmin afterwards. Keep the previous working selection recorded so you can restore it.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Step 4 — Understand public access before enabling anything</span></span><br />
1. In the same management window, open <span style="font-weight: bold;" class="mycode_b">Service</span>.<br />
2. Find <span style="font-weight: bold;" class="mycode_b">Enable public access</span>.<br />
3. Read the panel's explanation before changing the checkbox.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Our verified state:</span> The checkbox is unchecked. In this version, the panel explains that authenticated panel access is separate from the public phpMyAdmin service. The numbered screenshot highlights the checkbox and explanation; the private access address has been hidden.<br />
<br />
<img src="https://adminsforum.com/attachment.php?aid=10" loading="lazy"  alt="[Image: attachment.php?aid=10]" class="mycode_img" /><br />
<br />
<span style="font-weight: bold;" class="mycode_b">Why leave it off?</span> You do not need an additional publicly reachable database-administration page just to learn the panel workflow. Do not enable public access or open its firewall port merely because an older tutorial uses a public URL. This guide does not change firewall rules or enable that service.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Step 5 — Locate the database you intend to manage</span></span><br />
1. Close the phpMyAdmin settings window.<br />
2. Open <span style="font-weight: bold;" class="mycode_b">Databases</span> from the left menu.<br />
3. Find the application database by its name and remark.<br />
4. Note the database name and associated username privately.<br />
5. Use the row's <span style="font-weight: bold;" class="mycode_b">phpMyAdmin</span> action for the intended database.<br />
<br />
If no application database exists, create it first using our <a href="https://adminsforum.com/Thread-guide-create-a-database-and-user-in-aapanel-free-edition" target="_blank" rel="noopener" class="mycode_url">database and user guide</a>. Do not select a database just because it appears first in the list.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Step 6 — Try authenticated panel access</span></span><br />
The database access dialog in our lab offers <span style="font-weight: bold;" class="mycode_b">Password-free access</span> and <span style="font-weight: bold;" class="mycode_b">Public access</span>. Choose <span style="font-weight: bold;" class="mycode_b">Password-free access</span> first while logged into the panel.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">What happened in our test:</span> aaPanel opened an aaPanel account registration/login prompt. This is the vendor account prompt, not a MySQL login. Until that account step is completed, we cannot demonstrate the database browsing screen through this route. If you encounter the same prompt, use your own account and follow its verification process. Do not paste account credentials into support posts.<br />
<br />
If nothing opens, check whether the browser blocked a popup and retry the same authenticated action. If the vendor account step is completed but access still fails, record the exact response rather than switching to public access as an automatic workaround.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Step 7 — Know which password belongs where</span></span><ul class="mycode_list"><li><span style="font-weight: bold;" class="mycode_b">aaPanel server login:</span> Signs into the control panel installed on your VPS.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">aaPanel vendor account:</span> Signs into aaPanel's account service when a feature requests it.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">MySQL/MariaDB user:</span> Identifies the database account used by phpMyAdmin or your application.<br />
</li>
</ul>
If you reach a phpMyAdmin database-login form, it expects valid database credentials. The aaPanel server password is not a replacement for the database password. Prefer a user assigned to the application database for routine work rather than a database root account.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Troubleshooting: decide from the actual symptom</span></span><ul class="mycode_list"><li><span style="font-weight: bold;" class="mycode_b">App does not appear installed:</span> Check the installation task result and app list. Do not assume a clicked Install button completed successfully.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">502 or blank page:</span> Check phpMyAdmin's selected PHP runtime, the corresponding PHP service and relevant error logs. Check this runtime independently of the website's PHP version.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Vendor login prompt:</span> Complete the account step. It does not mean the database password is wrong.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Database access denied:</span> Check the database username, password, host and grants. Copy the error number after removing secrets.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Expected database missing:</span> Confirm that it exists in aaPanel and that the database user has access to it. Stop before importing into another database.<br />
</li>
</ul>
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Practice and completion checklist</span></span><br />
Without changing any data, practise finding phpMyAdmin in the App Store, identifying its selected PHP runtime, locating your application's database, and explaining the difference between the three account types above.<br />
<br />
You have completed <span style="font-weight: bold;" class="mycode_b">setup preparation</span> when the app is installed, its runtime is identified, the intended database/user exists, and the access route is understood. You have completed <span style="font-weight: bold;" class="mycode_b">database access verification</span> only after the intended database actually opens. Our browser access verification is still pending; screenshots of browsing, export and import will be added after successful tests.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Next lessons:</span><ul class="mycode_list"><li><a href="https://adminsforum.com/Thread-guide-create-a-database-and-user-in-aapanel-free-edition" target="_blank" rel="noopener" class="mycode_url">Create a database and user</a><br />
</li>
<li><a href="https://adminsforum.com/Thread-guide-back-up-and-restore-a-database-in-aapanel-free-edition" target="_blank" rel="noopener" class="mycode_url">Test a database backup and restore using aaPanel</a><br />
</li>
<li><a href="https://adminsforum.com/Thread-guide-read-website-error-logs-in-aapanel-free-edition-nginx" target="_blank" rel="noopener" class="mycode_url">Read website error logs</a><br />
</li>
</ul>
<span style="font-weight: bold;" class="mycode_b">References:</span> <a href="https://docs.phpmyadmin.net/en/latest/intro.html" target="_blank" rel="noopener" class="mycode_url">phpMyAdmin introduction and database user explanation</a>; <a href="https://www.aapanel.com/docs/Function/AppStore.html" target="_blank" rel="noopener" class="mycode_url">aaPanel App Store documentation</a>. This walkthrough uses original AdminsForum lab captures and does not claim a completed video recording.<br /><!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=10" target="_blank" title="">phpmyadmin-annotated-20261010.jpg</a> (Size: 53.66 KB / Downloads: 25)
<!-- end: postbit_attachments_attachment -->]]></description>
			<content:encoded><![CDATA[<span style="font-weight: bold;" class="mycode_b">phpMyAdmin is a browser tool for working with MySQL or MariaDB databases. In this beginner guide, you will learn how to find its aaPanel installation, check its PHP runtime, understand its access settings, and prepare the correct database login.</span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">Lab verification:</span> Ubuntu 22.04.5, aaPanel Free Edition 8.0.6, phpMyAdmin 5.2 and MariaDB. Installation was completed with our original stack; management screens were checked again on 11 October 2026. phpMyAdmin uses PHP-84 while our website uses PHP 8.5. The panel's private launch currently requests an aaPanel vendor account login. Database browsing, import and export are not yet verified through that browser route.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Before you start: understand the three components</span></span><ul class="mycode_list"><li><span style="font-weight: bold;" class="mycode_b">MariaDB/MySQL:</span> The database server that stores your site's data.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">PHP:</span> The runtime that executes phpMyAdmin and PHP applications.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">phpMyAdmin:</span> A graphical tool that connects to the database server. It does not replace that server.<br />
</li>
</ul>
A website can use its database without phpMyAdmin being installed. Installing phpMyAdmin also does not create a WordPress database or a database user automatically.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">You need:</span> Access to your aaPanel, an installed database server, a compatible installed PHP runtime, and a database/user if you want to administer application data. Use a test database for practice. Back up an existing database before changing its contents.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Step 1 — Find phpMyAdmin in the App Store</span></span><br />
1. Sign in to your own aaPanel.<br />
2. Click <span style="font-weight: bold;" class="mycode_b">App Store</span> in the left menu.<br />
3. Enter <span style="font-weight: bold;" class="mycode_b">phpMyAdmin</span> in the app search field and submit the search.<br />
4. Locate the official phpMyAdmin row.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">What you should see:</span> Our lab shows <span style="font-weight: bold;" class="mycode_b">phpMyAdmin 5.2</span>, price <span style="font-weight: bold;" class="mycode_b">Free</span>, and <span style="font-weight: bold;" class="mycode_b">Setting</span> and <span style="font-weight: bold;" class="mycode_b">Uninstall</span> actions. These actions indicate that it is already installed. Do not uninstall it just to follow an installation guide.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">AdminsForum lab screenshot — the installed app entry</span><br />
<img src="https://adminsforum.com/uploads/tutorials/phpmyadmin-app-entry-branded-20261011.png" loading="lazy"  alt="[Image: phpmyadmin-app-entry-branded-20261011.png]" class="mycode_img" /><br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Step 2 — Install only if the app is missing</span></span><br />
If your row offers <span style="font-weight: bold;" class="mycode_b">Install</span>, select it, follow the panel's installation dialog, and wait until the task reports completion. Do not close or repeat the installation while its task is still running. Return to the app search and confirm that <span style="font-weight: bold;" class="mycode_b">Setting</span> is available.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Why this check matters:</span> Starting a task is not the same as completing it. If installation fails, record the actual message and inspect the task log before trying again. The screenshot above shows the completed installation state; it does not show a fresh installation dialog.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Step 3 — Check the PHP runtime used by phpMyAdmin</span></span><br />
1. Click <span style="font-weight: bold;" class="mycode_b">Setting</span> on the phpMyAdmin row.<br />
2. Select <span style="font-weight: bold;" class="mycode_b">PHP version</span> in the management window.<br />
3. Read the currently selected runtime.<br />
4. If it is already a suitable installed PHP version, leave it unchanged.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">What you should see:</span> Our selection is <span style="font-weight: bold;" class="mycode_b">PHP-84</span>, meaning PHP 8.4. The screenshot also offers PHP-85. This guide does not switch phpMyAdmin to 8.5 or claim that this switch was tested.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">AdminsForum lab screenshot — phpMyAdmin's own PHP selection</span><br />
<img src="https://adminsforum.com/uploads/tutorials/phpmyadmin-runtime-detail-branded-20261011.png" loading="lazy"  alt="[Image: phpmyadmin-runtime-detail-branded-20261011.png]" class="mycode_img" /><br />
<br />
<span style="font-weight: bold;" class="mycode_b">Why this matters:</span> The website PHP selection and phpMyAdmin PHP selection are separate. Changing your website to PHP 8.5 does not mean phpMyAdmin must use 8.5. <span style="font-weight: bold;" class="mycode_b">Static</span> is not an appropriate runtime for a PHP application. If you deliberately change this selection, choose an installed compatible runtime, click <span style="font-weight: bold;" class="mycode_b">Save</span>, and test opening phpMyAdmin afterwards. Keep the previous working selection recorded so you can restore it.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Step 4 — Understand public access before enabling anything</span></span><br />
1. In the same management window, open <span style="font-weight: bold;" class="mycode_b">Service</span>.<br />
2. Find <span style="font-weight: bold;" class="mycode_b">Enable public access</span>.<br />
3. Read the panel's explanation before changing the checkbox.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Our verified state:</span> The checkbox is unchecked. In this version, the panel explains that authenticated panel access is separate from the public phpMyAdmin service. The numbered screenshot highlights the checkbox and explanation; the private access address has been hidden.<br />
<br />
<img src="https://adminsforum.com/attachment.php?aid=10" loading="lazy"  alt="[Image: attachment.php?aid=10]" class="mycode_img" /><br />
<br />
<span style="font-weight: bold;" class="mycode_b">Why leave it off?</span> You do not need an additional publicly reachable database-administration page just to learn the panel workflow. Do not enable public access or open its firewall port merely because an older tutorial uses a public URL. This guide does not change firewall rules or enable that service.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Step 5 — Locate the database you intend to manage</span></span><br />
1. Close the phpMyAdmin settings window.<br />
2. Open <span style="font-weight: bold;" class="mycode_b">Databases</span> from the left menu.<br />
3. Find the application database by its name and remark.<br />
4. Note the database name and associated username privately.<br />
5. Use the row's <span style="font-weight: bold;" class="mycode_b">phpMyAdmin</span> action for the intended database.<br />
<br />
If no application database exists, create it first using our <a href="https://adminsforum.com/Thread-guide-create-a-database-and-user-in-aapanel-free-edition" target="_blank" rel="noopener" class="mycode_url">database and user guide</a>. Do not select a database just because it appears first in the list.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Step 6 — Try authenticated panel access</span></span><br />
The database access dialog in our lab offers <span style="font-weight: bold;" class="mycode_b">Password-free access</span> and <span style="font-weight: bold;" class="mycode_b">Public access</span>. Choose <span style="font-weight: bold;" class="mycode_b">Password-free access</span> first while logged into the panel.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">What happened in our test:</span> aaPanel opened an aaPanel account registration/login prompt. This is the vendor account prompt, not a MySQL login. Until that account step is completed, we cannot demonstrate the database browsing screen through this route. If you encounter the same prompt, use your own account and follow its verification process. Do not paste account credentials into support posts.<br />
<br />
If nothing opens, check whether the browser blocked a popup and retry the same authenticated action. If the vendor account step is completed but access still fails, record the exact response rather than switching to public access as an automatic workaround.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Step 7 — Know which password belongs where</span></span><ul class="mycode_list"><li><span style="font-weight: bold;" class="mycode_b">aaPanel server login:</span> Signs into the control panel installed on your VPS.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">aaPanel vendor account:</span> Signs into aaPanel's account service when a feature requests it.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">MySQL/MariaDB user:</span> Identifies the database account used by phpMyAdmin or your application.<br />
</li>
</ul>
If you reach a phpMyAdmin database-login form, it expects valid database credentials. The aaPanel server password is not a replacement for the database password. Prefer a user assigned to the application database for routine work rather than a database root account.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Troubleshooting: decide from the actual symptom</span></span><ul class="mycode_list"><li><span style="font-weight: bold;" class="mycode_b">App does not appear installed:</span> Check the installation task result and app list. Do not assume a clicked Install button completed successfully.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">502 or blank page:</span> Check phpMyAdmin's selected PHP runtime, the corresponding PHP service and relevant error logs. Check this runtime independently of the website's PHP version.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Vendor login prompt:</span> Complete the account step. It does not mean the database password is wrong.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Database access denied:</span> Check the database username, password, host and grants. Copy the error number after removing secrets.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Expected database missing:</span> Confirm that it exists in aaPanel and that the database user has access to it. Stop before importing into another database.<br />
</li>
</ul>
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Practice and completion checklist</span></span><br />
Without changing any data, practise finding phpMyAdmin in the App Store, identifying its selected PHP runtime, locating your application's database, and explaining the difference between the three account types above.<br />
<br />
You have completed <span style="font-weight: bold;" class="mycode_b">setup preparation</span> when the app is installed, its runtime is identified, the intended database/user exists, and the access route is understood. You have completed <span style="font-weight: bold;" class="mycode_b">database access verification</span> only after the intended database actually opens. Our browser access verification is still pending; screenshots of browsing, export and import will be added after successful tests.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Next lessons:</span><ul class="mycode_list"><li><a href="https://adminsforum.com/Thread-guide-create-a-database-and-user-in-aapanel-free-edition" target="_blank" rel="noopener" class="mycode_url">Create a database and user</a><br />
</li>
<li><a href="https://adminsforum.com/Thread-guide-back-up-and-restore-a-database-in-aapanel-free-edition" target="_blank" rel="noopener" class="mycode_url">Test a database backup and restore using aaPanel</a><br />
</li>
<li><a href="https://adminsforum.com/Thread-guide-read-website-error-logs-in-aapanel-free-edition-nginx" target="_blank" rel="noopener" class="mycode_url">Read website error logs</a><br />
</li>
</ul>
<span style="font-weight: bold;" class="mycode_b">References:</span> <a href="https://docs.phpmyadmin.net/en/latest/intro.html" target="_blank" rel="noopener" class="mycode_url">phpMyAdmin introduction and database user explanation</a>; <a href="https://www.aapanel.com/docs/Function/AppStore.html" target="_blank" rel="noopener" class="mycode_url">aaPanel App Store documentation</a>. This walkthrough uses original AdminsForum lab captures and does not claim a completed video recording.<br /><!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=10" target="_blank" title="">phpmyadmin-annotated-20261010.jpg</a> (Size: 53.66 KB / Downloads: 25)
<!-- end: postbit_attachments_attachment -->]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[Install MariaDB in aaPanel Free Edition]]></title>
			<link>https://adminsforum.com/Thread-guide-install-mariadb-in-aapanel-free-edition</link>
			<pubDate>Sat, 10 Oct 2026 23:27:49 +0800</pubDate>
			<dc:creator><![CDATA[<a href="https://adminsforum.com/member.php?action=profile&uid=2">DEV</a>]]></dc:creator>
			<guid isPermaLink="false">https://adminsforum.com/Thread-guide-install-mariadb-in-aapanel-free-edition</guid>
			<description><![CDATA[Install MariaDB in aaPanel Free Edition to provide a database server for applications that support it. Verify the service before creating an application database. A running database server and a database/user created for a website are different steps.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Tested environment</span><br />
Ubuntu 22.04.5 and aaPanel Free Edition 8.0.6. MariaDB was selected during our first-login stack installation. On 10 October 2026, the server reported MariaDB 10.11.10 and its database service was active. Some panel labels still use “MySQL” because this screen manages the compatible database server.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">1. Select MariaDB</span><br />
On a fresh panel, choose MariaDB in the database selector of the recommended stack dialog. If that dialog has already been dismissed, open <span style="font-weight: bold;" class="mycode_b">App Store</span>, locate the database server and use <span style="font-weight: bold;" class="mycode_b">Install</span> to choose an available MariaDB version. Follow the task until completion. If MariaDB is already installed, proceed to its settings.<br />
<br />
Use one database server for this beginner setup. Do not uninstall an existing MySQL/MariaDB instance or replace its data directory to follow a fresh-install tutorial. Changing database engines on a populated server requires a separate backup and migration plan.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">2. Verify the running service</span><br />
Open <span style="font-weight: bold;" class="mycode_b">App Store → Installed → MariaDB → Setting</span>. Our service window is titled MySQL. In the screenshot, <span style="font-weight: bold;" class="mycode_b">1</span> marks the running state, <span style="font-weight: bold;" class="mycode_b">2</span> the service controls and <span style="font-weight: bold;" class="mycode_b">3</span> the Error log.<br />
<img src="https://adminsforum.com/attachment.php?aid=9" loading="lazy"  alt="[Image: attachment.php?aid=9]" class="mycode_img" /><br />
<br />
Use SSH to confirm the binary version and service status:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>/www/server/mysql/bin/mysql --version
/etc/init.d/mysqld status</code></div></div>These checks do not require publishing or changing the database root password. We verified an active service on the lab. The version command alone only proves that the client binary is present.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">3. Prepare for your application</span><br />
Open <span style="font-weight: bold;" class="mycode_b">Databases</span> in aaPanel. Create a separate database and user for each application when you deploy it, and keep that user's permissions limited to its own database. Store the credentials privately in the application's configuration. Panel login credentials are not database credentials.<br />
<br />
For a website on the same server, keep database access local. Opening port 3306 to the entire internet is unnecessary. Our lab firewall does not allow public access to that port.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Troubleshooting</span><br />
If the service will not start, read the Error log and check available disk space. For an application's “access denied” error, check its database name, user, password and host. Do not reset the database root password or reinstall the server as the first response.<br />
<br />
<a href="https://adminsforum.com/Thread-guide-install-aapanel-free-edition-on-ubuntu-22-04" target="_blank" rel="noopener" class="mycode_url">Install aaPanel Free Edition on Ubuntu 22.04</a><br />
<a href="https://adminsforum.com/Thread-guide-aapanel-free-edition-install-nginx-php-mariadb" target="_blank" rel="noopener" class="mycode_url">Web stack setup and tutorial series</a><br />
<a href="https://adminsforum.com/Thread-guide-secure-aapanel-free-edition-https-ssh-keys-panel-port" target="_blank" rel="noopener" class="mycode_url">Secure aaPanel Free Edition</a><br />
<br />
<a href="https://www.aapanel.com/docs/Function/AppStore.html" target="_blank" rel="noopener" class="mycode_url">Official aaPanel App Store documentation</a><br /><!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=9" target="_blank" title="">mariadb-annotated-20261010.jpg</a> (Size: 52.81 KB / Downloads: 11)
<!-- end: postbit_attachments_attachment -->]]></description>
			<content:encoded><![CDATA[Install MariaDB in aaPanel Free Edition to provide a database server for applications that support it. Verify the service before creating an application database. A running database server and a database/user created for a website are different steps.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Tested environment</span><br />
Ubuntu 22.04.5 and aaPanel Free Edition 8.0.6. MariaDB was selected during our first-login stack installation. On 10 October 2026, the server reported MariaDB 10.11.10 and its database service was active. Some panel labels still use “MySQL” because this screen manages the compatible database server.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">1. Select MariaDB</span><br />
On a fresh panel, choose MariaDB in the database selector of the recommended stack dialog. If that dialog has already been dismissed, open <span style="font-weight: bold;" class="mycode_b">App Store</span>, locate the database server and use <span style="font-weight: bold;" class="mycode_b">Install</span> to choose an available MariaDB version. Follow the task until completion. If MariaDB is already installed, proceed to its settings.<br />
<br />
Use one database server for this beginner setup. Do not uninstall an existing MySQL/MariaDB instance or replace its data directory to follow a fresh-install tutorial. Changing database engines on a populated server requires a separate backup and migration plan.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">2. Verify the running service</span><br />
Open <span style="font-weight: bold;" class="mycode_b">App Store → Installed → MariaDB → Setting</span>. Our service window is titled MySQL. In the screenshot, <span style="font-weight: bold;" class="mycode_b">1</span> marks the running state, <span style="font-weight: bold;" class="mycode_b">2</span> the service controls and <span style="font-weight: bold;" class="mycode_b">3</span> the Error log.<br />
<img src="https://adminsforum.com/attachment.php?aid=9" loading="lazy"  alt="[Image: attachment.php?aid=9]" class="mycode_img" /><br />
<br />
Use SSH to confirm the binary version and service status:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>/www/server/mysql/bin/mysql --version
/etc/init.d/mysqld status</code></div></div>These checks do not require publishing or changing the database root password. We verified an active service on the lab. The version command alone only proves that the client binary is present.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">3. Prepare for your application</span><br />
Open <span style="font-weight: bold;" class="mycode_b">Databases</span> in aaPanel. Create a separate database and user for each application when you deploy it, and keep that user's permissions limited to its own database. Store the credentials privately in the application's configuration. Panel login credentials are not database credentials.<br />
<br />
For a website on the same server, keep database access local. Opening port 3306 to the entire internet is unnecessary. Our lab firewall does not allow public access to that port.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Troubleshooting</span><br />
If the service will not start, read the Error log and check available disk space. For an application's “access denied” error, check its database name, user, password and host. Do not reset the database root password or reinstall the server as the first response.<br />
<br />
<a href="https://adminsforum.com/Thread-guide-install-aapanel-free-edition-on-ubuntu-22-04" target="_blank" rel="noopener" class="mycode_url">Install aaPanel Free Edition on Ubuntu 22.04</a><br />
<a href="https://adminsforum.com/Thread-guide-aapanel-free-edition-install-nginx-php-mariadb" target="_blank" rel="noopener" class="mycode_url">Web stack setup and tutorial series</a><br />
<a href="https://adminsforum.com/Thread-guide-secure-aapanel-free-edition-https-ssh-keys-panel-port" target="_blank" rel="noopener" class="mycode_url">Secure aaPanel Free Edition</a><br />
<br />
<a href="https://www.aapanel.com/docs/Function/AppStore.html" target="_blank" rel="noopener" class="mycode_url">Official aaPanel App Store documentation</a><br /><!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=9" target="_blank" title="">mariadb-annotated-20261010.jpg</a> (Size: 52.81 KB / Downloads: 11)
<!-- end: postbit_attachments_attachment -->]]></content:encoded>
		</item>
	</channel>
</rss>