<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>import Archives - Alexandros Georgiou</title>
	<atom:link href="https://www.alexgeorgiou.gr/tag/import/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.alexgeorgiou.gr/tag/import/</link>
	<description>Balancing brackets for a living</description>
	<lastBuildDate>Tue, 22 Aug 2023 10:59:09 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	

<image>
	<url>https://www.alexgeorgiou.gr/wp-content/uploads/2021/07/cropped-alexgeorgiou-icon-32x32.png</url>
	<title>import Archives - Alexandros Georgiou</title>
	<link>https://www.alexgeorgiou.gr/tag/import/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>auto_increment flag repair on primary keys of a WordPress MySQL database</title>
		<link>https://www.alexgeorgiou.gr/repair-auto_increment-primary-key-wordpress-mysql/</link>
					<comments>https://www.alexgeorgiou.gr/repair-auto_increment-primary-key-wordpress-mysql/#comments</comments>
		
		<dc:creator><![CDATA[alexg]]></dc:creator>
		<pubDate>Sun, 18 Dec 2016 12:52:02 +0000</pubDate>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[auto_increment]]></category>
		<category><![CDATA[backup]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[error]]></category>
		<category><![CDATA[export]]></category>
		<category><![CDATA[import]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[mysqldump]]></category>
		<category><![CDATA[primary key]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[wordpress]]></category>
		<guid isPermaLink="false">http://www.alexgeorgiou.gr/?p=173</guid>

					<description><![CDATA[<p>Here's some code to restore the auto_increment flag on the primary keys of a WordPress MySQL database after a faulty export/import cycle.</p>
<p>The post <a href="https://www.alexgeorgiou.gr/repair-auto_increment-primary-key-wordpress-mysql/">auto_increment flag repair on primary keys of a WordPress MySQL database</a> appeared first on <a href="https://www.alexgeorgiou.gr">Alexandros Georgiou</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p><em>Here&#8217;s some code that I used to restore the auto_increment flag on the primary keys of my WordPress MySQL database after a somewhat faulty export/import cycle.</em></p>



<h2 class="wp-block-heading">The auto_increment problem and its symptoms</h2>



<p>When you export the WordPress database and then import it again, either via <code>phpmyadmin</code> or via <code>mysqldump</code> and the <code>mysql</code> CLI, all sorts of things can (and often will) go wrong. This can be understandably very stressful, especially on a live system. Please take a deep breath and read on.</p>



<p>I did a dump of my (fortunately development) environment and then imported it again. At first glance, all was working perfectly.</p>



<p>Then, all of a sudden I noticed that the <strong>Administrator</strong> user had no rights to create posts or pages. The usual <strong>Publish</strong> button was replaced with <strong>Submit for review</strong>.</p>



<p>Naïvely my first thought was to install <a href="https://wordpress.org/plugins/user-role-editor/" target="_blank" rel="noopener noreferrer">a plugin to fix roles and capabilities</a>. Sure enough, the admin user had no right to create posts or pages. When I tried to give those rights, I saw the following in my logs:</p>



<pre class="wp-block-preformatted">PHP message: WordPress database error Duplicate entry '0' for key 'PRIMARY' for query INSERT INTO `wp_usermeta` (`user_id`, `meta_key`, `meta_value`) VALUES (1, 'wp_capabilities', 'a:1:{s:13:\"administrator\";b:1;}') made by require_once('wp-admin/admin.php'), do_action('users_page_users-user-role-editor'), User_Role_Editor-&gt;edit_roles, Ure_Lib-&gt;editor, Ure_Lib-&gt;process_user_request, Ure_Lib-&gt;permissions_object_update, Ure_Lib-&gt;update_user, WP_User-&gt;add_role, update_user_meta, update_metadata, add_metadata</pre>



<p>(I have debug logs enabled in my development environment. If you&#8217;re in a production environment you might not see this.)</p>



<p>Why would a primary key be set to <code>0</code> you ask? A quick glance at the structure of the <code>wp_usermeta</code> table via <code>phpmyadmin</code> reveals that the primary key column had no <code>auto_increment</code> flag.</p>



<p>SQL <code>INSERT</code> statements from various plugins were inserting rows in various tables with the primary key being undefined (and therefore set to a default of <code>0</code>). Since primary keys have a unique constraint, attempting to do a second insert to the same table fails, causing all sorts of havoc.</p>



<p><strong>For some reason the <code>auto_increment</code> flag had not been preserved when I re-imported the SQL dump.</strong> Everything else seemed to be in order though. I did not investigate why this happened but decided to simply fix this.</p>



<h2 class="wp-block-heading">Coding is the solution</h2>



<p>By now I could see the front-end but was not able to login to the admin interface any more. Any <code>INSERT</code> query to the database, including those that store session information upon login, were failing. As I had quite a lot of tables, I decided not to do this manually, but to write a generic script.</p>



<p>As a side-note, the script needs to connect with the <code>NO_ZERO_DATE</code> SQL mode. WordPress uses a lot of <code>DATETIME</code> fields with a default value of <code>0000-00-00 00:00:00</code> and this script will be <strong>very unhappy</strong> if this mode is not set.</p>



<h3 class="wp-block-heading">Pseudocode</h3>



<pre class="wp-block-preformatted">for all tables in database
&nbsp;&nbsp;&nbsp; get the primary key column's name and type
&nbsp;&nbsp;&nbsp; get the next available primary key value
&nbsp;&nbsp;&nbsp; change the row with zero primary key so it has the next available primary key
&nbsp;&nbsp;&nbsp; set the auto_increment flag to the primary key column</pre>



<p><strong>Note: The above assumes that all the primary keys are numeric. YMMV.</strong></p>



<h3 class="wp-block-heading">What to do:</h3>



<p>Next is a PHP listing of the above solution. Here&#8217;s what to do:</p>



<ol class="wp-block-list">
<li><strong>Check to see that your issue is actually one of missing auto_increment flags.</strong> This script will only repair this particular error.</li>



<li><strong>Check to see that all your primary keys are numeric.</strong> There shouldn&#8217;t be an issue if some aren&#8217;t but you might have to hack the code manually or go update the structure of those tables via <code>phpmyadmin</code>.</li>



<li><strong>Change the host, dbname, username and password in the code to those that match your system.</strong></li>



<li><strong>Backup your database</strong> (I guess you already have a backup and that&#8217;s what caused the issue, but still, you want to be able to go back if something goes wrong when running this.) You are solely responsible for any damages including data loss from running this script. Don&#8217;t blame me for corrupting your data please. Read and understand the code first!</li>
</ol>



<h3 class="wp-block-heading">The PHP script</h3>



<p>Save this in a file, take another deep breath, and run it via the PHP CLI. I hope it solves your MySQL woes. Good luck buddy.</p>



<pre class="wp-block-preformatted">&lt;?php

// change these settings
$servername = 'localhost';
$username = 'dbuser';
$password = 'password';
$db = 'database';

// connect
$conn = new mysqli($servername, $username, $password);
try {
&nbsp;&nbsp; &nbsp;$conn = new PDO("mysql:host=$servername;dbname=$db", $username, $password, array(PDO::MYSQL_ATTR_INIT_COMMAND =&gt; 'SET sql_mode="NO_ZERO_DATE"') );
&nbsp;&nbsp; &nbsp;$conn-&gt;setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
&nbsp;&nbsp; &nbsp;echo "Connected successfully";
} catch(PDOException $e) {
&nbsp;&nbsp; &nbsp;exit( "Connection failed: " . $e-&gt;getMessage() );
}

// get all table names
$stm = $conn-&gt;prepare('SHOW TABLES');
$stm-&gt;execute();
$table_names = array();
foreach ( $stm-&gt;fetchAll() as $row ) {
&nbsp;&nbsp; &nbsp;$table_names[] = $row[0];
}

// for all tables
foreach ( $table_names as $table_name ) {
&nbsp;&nbsp; &nbsp;echo "\nRepairing table $table_name...\n";

&nbsp;&nbsp; &nbsp;// get the primary key name
&nbsp;&nbsp; &nbsp;$stm = $conn-&gt;prepare( "show keys from $table_name where Key_name = 'PRIMARY'" );
&nbsp;&nbsp; &nbsp;$stm-&gt;execute();
&nbsp;&nbsp; &nbsp;$key_name = $stm-&gt;fetch()['Column_name'];

&nbsp;&nbsp; &nbsp;// get the primary key type
&nbsp;&nbsp; &nbsp;$stm = $conn-&gt;prepare( "show fields from $table_name where Field = '$key_name'" );
&nbsp;&nbsp; &nbsp;$stm-&gt;execute();
&nbsp;&nbsp; &nbsp;$key_type = $stm-&gt;fetch()['Type'];

&nbsp;&nbsp; &nbsp;// if there is a primary key
&nbsp;&nbsp; &nbsp;if ($key_name) {
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;echo "Primary key is $key_name\n";

&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;try {
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;// if auto_increment was missing there might be a row with key=0 . compute the next available primary key
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;$sql = "select (ifnull( max($key_name), 0)+1) as next_id from $table_name";
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;$stm = $conn-&gt;prepare( $sql );
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;echo "$sql\n";
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;$stm-&gt;execute();
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;$next_id = $stm-&gt;fetch()['next_id'];

&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;// give a sane primary key to a row that has key = 0 if it exists
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;$sql = "update $table_name set $key_name = $next_id where $key_name = 0";
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;echo "$sql\n";
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;$stm = $conn-&gt;prepare( $sql );
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;$stm-&gt;execute();

&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;// set auto_increment to the primary key
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;$sql = "alter table $table_name modify column $key_name $key_type auto_increment";
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;echo "$sql\n";
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;$stm = $conn-&gt;prepare( $sql );
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;$stm-&gt;execute();

&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;} catch (PDOException $e) {
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;echo "\n\nQuery: $sql\nError:" . $e-&gt;getMessage() . "\n\n";
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}
&nbsp;&nbsp; &nbsp;} else {
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;echo "No primary key found for table $table_name.\n";
&nbsp;&nbsp; &nbsp;}
}
echo "\n\nFinished\n";
$conn = null;

</pre>



<p>If I have helped you get your site up and running, you can donate a few Satoshis at: <a href="bitcoin:bc1qjkgp8u2jwy2n9k20avjweuy7etsjfpfplvf99q">bc1qjkgp8u2jwy2n9k20avjweuy7etsjfpfplvf99q</a></p>
<p>The post <a href="https://www.alexgeorgiou.gr/repair-auto_increment-primary-key-wordpress-mysql/">auto_increment flag repair on primary keys of a WordPress MySQL database</a> appeared first on <a href="https://www.alexgeorgiou.gr">Alexandros Georgiou</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.alexgeorgiou.gr/repair-auto_increment-primary-key-wordpress-mysql/feed/</wfw:commentRss>
			<slash:comments>41</slash:comments>
		
		
			</item>
	</channel>
</rss>
