WordPress 로그인 불가 문제 해결

Page content

말썽쟁이(?) wordpress 블로그가 또 문제를 일으켰다.
이번에도 로그인이 안되는 현상인데 지난 번과는 다른 에러 메시지가 나온다. 즉 지난 번 해결책은 소용이 없을 거라는 불길한 예감이.

wordpress_login_error_account_is_missing

로그인 계정 자체가 없다는 이 어이없는 상황.

그래서 지난 번에 유용하게 사용했던 phpmyadmin을 이용해서 DB 정보를 확인해봤다. (다행히 MySql, wordpress 와 함께 실행시켜놓은 phpmyadmin container가 동작하고 있어서 지난 번과 같이 8181 포트로 접속하면 된단. 다만 로그인 암호를 기억하지 못하고 있는 나 대신 Safari가 기억하고 있어서 그냥 접속했다는)

phpmyadmin_wordpress_db_tablespace_missing

뭔가 이상하다.

#1812 - Tablespace is missing for table wordpress_db.wp_users.

이게 무슨 말인가 하고 구글링을 해 보니 DB 파일에 문제가 생겨서 그렇다고. 이걸 해결하려면 이전에 백업한 DB 파일이 있어야 한다는 청천벽력 같은 말. 거기에 전에 DB를 모두 restore하는 방식으로 해결했다는 글이 보인다. ERROR 1812 (HY000): Tablespace is missing for table in MYSQL

Solution We must have backup for restore, We have taken on Sunday, deletion of TEST2 happen on Monday.

음.. 이러면 백업된 시점 이후에 변경된 내용은 모두 잃어버린다는 것 같은데

다른 글에서는 일단 db 파일에 문제가 생긴 경우(파일이 없거나, 파일 퍼미션이 정상이 아닌에도 동일한 문제가 발생할 수 있다고. How to fix error “1812 Tablespace is missing for table XXXX”

  • Table files have the wrong ownership/permissions
  • The table file is misplaced
  • The data file is corrupted or deleted

만일 idb 파일에 문제가 생긴 경우라면 문제가 생긴 파일만 백업 본으로 교체하거나 파일 권한을 수정하면 간단하게 해결이 될 거고, SQL DB 전체에 대한 거라면 역시나 기존 DB를 지우고 백업된 걸로 복원을 해야 한다고

If the backups are stored as .ibd files, we copy the table files into the database folder and set the right permissions. Everything usually works fine from that point. On the other hand, if it’s in the SQL format, we drop the current database, and restore the full database from backup. This method will create fresh entries in the System tables, and build proper linkages.

그나마 이건 백업 본이 있을 때나 하는 이야기고…

그래서 mysql container에 접속해서 확인해 보니 과연 위에서 에러난 table 파일만 찾을 수 없다. 아무리 봐도 wordpress 버전 업그레이드를 하면서 일부 파일에 문제가 생긴 듯…

cychong@mini1:~$ sudo docker ps -a |grep mysql
[sudo] password for cychong: 
faafa54b9184        mysql:8                   "docker-entrypoint.s…"   2 months ago        Up 2 days                   3306/tcp, 33060/tcp    mysql

cychong@mini1:~$ sudo docker exec -it faafa54b9184  /bin/bash
root@faafa54b9184:/# find . -name *.ibd
find: './proc/1/map_files': Permission denied
./var/lib/mysql/wordpress_db/wp_options.ibd
./var/lib/mysql/wordpress_db/wp_postmeta.ibd
./var/lib/mysql/wordpress_db/wp_posts.ibd
./var/lib/mysql/wordpress_db/wp_usermeta.ibd
./var/lib/mysql/wordpress_db/wp_comments.ibd
./var/lib/mysql/wordpress_db/wp_commentmeta.ibd
./var/lib/mysql/wordpress_db/wp_terms.ibd
./var/lib/mysql/wordpress_db/wp_term_taxonomy.ibd
./var/lib/mysql/wordpress_db/wp_term_relationships.ibd
./var/lib/mysql/mysql.ibd
./var/lib/mysql/sys/sys_config.ibd

하지만 내 문제는 백업된 SQL이 파일이 없다는 거. 가진 건 XML 형태 뿐. 이걸로 어떻게 고칠 수 없을까?

일단 wp_users 외 다른 table에는 문제가 없는 각 table 별로 확인을 해보니(phpmyadmin에서 각 table별로 클릭해 보면 확인 가능) termmetalinks도 같은 에러가 있다. 첩첩산중이네.

wordpress_db_termmeta_has_error

아무래도 인터넷에 많이 있는 해결책으로는 내 문제를 해결할 수 없는 듯하다. 직접 문제를 해결해야 할 듯.

Table을 새로 만들어 보자

기존에 백업된 걸로 복원하는 방식을 사용할 수 없다면 새로 만드는 수 밖에. 다행히 posts table이 아니고 일단 로그인 문제는 users table만 관계된 듯 하니 문제가 된 table을 직접 만들어 보기로 했다. 구글링을 해서 users table의 구조(schema)를 찾아 보니 2019년 3월 29일에 작성된 이 글 이 있는데 문제는 1년 전에 작성된 이 글에 있는 내용이 최신 구조와 같은 지 판단하기 어렵다는. 그래서 추가로 확인해 보니 앞 글 보다 더 최근에 작성된 다른 글 에서는 조금 다른 형태라고 설명이 되어 있다. 예를 들면 user_pass가 64가 아니라 255비트로 늘어난 걸로. 아무래도 직접 wordpress 코드를 보고 파악하는게 낫겠다.(나중에 깨달았지만, 내가 사용하는 wordpress가 최신 버전이 아닌데 최신 코드를 보고 작업하는 게 맞는 거 였을까 싶은…)

wordpress.org에서 wordpress 소스 코드를 받아 보기로.

cychong15:workspace cychong$ wget https://wordpress.org/latest.tar.gz

wp-admin/includes/schema.php파일에 DB table을 만드는 코드가 있는 듯 한데 다음과 같이 정의되어 있다.

	// Single site users table. The multisite flavor of the users table is handled below.
	$users_single_table = "CREATE TABLE $wpdb->users (
	ID bigint(20) unsigned NOT NULL auto_increment,
	user_login varchar(60) NOT NULL default '',
	user_pass varchar(255) NOT NULL default '',
	user_nicename varchar(50) NOT NULL default '',
	user_email varchar(100) NOT NULL default '',
	user_url varchar(100) NOT NULL default '',
	user_registered datetime NOT NULL default '0000-00-00 00:00:00',
	user_activation_key varchar(255) NOT NULL default '',
	user_status int(11) NOT NULL default '0',
	display_name varchar(250) NOT NULL default '',
	PRIMARY KEY  (ID),
	KEY user_login_key (user_login),
	KEY user_nicename (user_nicename),
	KEY user_email (user_email)
) $charset_collate;\n";

(이것도 Single site인 경우와 Multi site 인 경우가 다른 듯 한데, 일단 난 single site인 걸로)

이제 구조를 알았으니 phpmyadmin을 이용해서 직접 DB에 users table을 추가하기로

고장난 집부터 부수기

일단 문제가 된 users table을 삭제하고, 새로 만들기로

recover_wp_delete_broken_table

그 다음 insert 메뉴를 통해 새로 users table을 추가해 본다.

recover_wp_create_users_table 위 Schema에 있는 대로 각 항목별 필드 이름, 타입(int, varchar or datetime) 등을 고르고, varchar 타입인 경우 길이 지정하고. user_registered 항목의 default 값이 0000-00-00 00:00:00으로 되어 있는데 이렇게 하면 에러가 난다.

구글링해보니 mysql 버전(설정?)에 따라 허용하지 않는 경우가 있다고. 내 경우는 허용하지 않는 상황인 듯. 그래서 그냥 1970-01-01로 변경

recover_wp_change_datetime_default

참고로 오른쪽 아래 있는 “Preview SQL” 을 클릭하면 실제로 수행될 SQL 명령을 볼 수 있다. 이걸 통해 위 php 코드에 있는 SQL 유사한 명령처럼 나오는 지 비교하면 편하다(예를 들면 not null 이나 auto_increment 등은 옵션이 눈에 띄지 않는데 각각 NULL, A.I 선택 버튼을 클릭한 후 SQL 명령을 확인해서 옵션을 제대로 골랐는 지 파악할 수 있다)

이제 명시적으로 정의해야 하는 필드 들은 모두 추가하고, ID를 primary key로 지정하는 건 알겠는데 나머지 3개 항목 user_login_key, user_nicename, user_emailKEY형태로 하는 건 어떻게 해야 하는 지 모르겠다. 각 항목별 옵션에 primary key 외에 그냥 key로 지정하는 건 없는 듯한데… 그래서 추가 검색해 보니 역시나 다른 옵션으로 보였던 INDEX를 사용하는 거 였다.

recover_wp_no_additional_indexes

recover_wp_add_index

나머지 항목들도 모두 추가

recover_wp_one_index_added

users table을 생성했으니 이제 실제 사용자 정보를 추가해 본다.

recover_wp_add_new_user

자 이제 제대로 복구했는지 wordpress admin 페이지에 접속해 보면

드.디.어.

recover_wp_finally_login_again

DB 망가진 지 몇 달만에 복구하는데 성공했다. 아직 다른 2개 table도 남아있긴 하지만 일단 로그인이 되니 좀 낫겠지.

백업!
백업! 백업!

중요하다. 중요해.