필자는 django에서 DataBase를 MySQL을 사용하려고 했다.
근데 GCP EC2를 사용해서 배포를 진행하려고 하니 계속 해서 Database에서 에러가 발생을 하였다.
SSH 서버에서 장고프로젝트로 들어간 후 migrate를 하려고 하니 밑에와 같은 에러가 발생했다.
(venv) srilankakim66@instance-20240510-021431:~/final_project$ python manage.py migrate
Traceback (most recent call last):
File "/home/srilankakim66/final_project/venv/lib/python3.11/site-packages/django/db/backends/base/base.py", line 275, in ensure_connection
self.connect()
File "/home/srilankakim66/final_project/venv/lib/python3.11/site-packages/django/utils/asyncio.py", line 26, in inner
return func(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^
File "/home/srilankakim66/final_project/venv/lib/python3.11/site-packages/django/db/backends/base/base.py", line 256, in connect
self.connection = self.get_new_connection(conn_params)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/srilankakim66/final_project/venv/lib/python3.11/site-packages/django/utils/asyncio.py", line 26, in inner
return func(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^
File "/home/srilankakim66/final_project/venv/lib/python3.11/site-packages/django/db/backends/mysql/base.py", line 256, in get_new_connection
connection = Database.connect(**conn_params)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/srilankakim66/final_project/venv/lib/python3.11/site-packages/MySQLdb/__init__.py", line 121, in Connect
return Connection(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/srilankakim66/final_project/venv/lib/python3.11/site-packages/MySQLdb/connections.py", line 195, in __init__
super().__init__(*args, **kwargs2)
MySQLdb.OperationalError: (2003, "Can't connect to MySQL server on '127.0.0.1:3306' (111)")
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/home/srilankakim66/final_project/manage.py", line 22, in <module>
main()
File "/home/srilankakim66/final_project/manage.py", line 18, in main
execute_from_command_line(sys.argv)
File "/home/srilankakim66/final_project/venv/lib/python3.11/site-packages/django/core/management/__init__.py", line 442, in execute_from_command_line
utility.execute()
File "/home/srilankakim66/final_project/venv/lib/python3.11/site-packages/django/core/management/__init__.py", line 436, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/home/srilankakim66/final_project/venv/lib/python3.11/site-packages/django/core/management/base.py", line 413, in run_from_argv
self.execute(*args, **cmd_options)
File "/home/srilankakim66/final_project/venv/lib/python3.11/site-packages/django/core/management/base.py", line 459, in execute
output = self.handle(*args, **options)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/srilankakim66/final_project/venv/lib/python3.11/site-packages/django/core/management/base.py", line 107, in wrapper
res = handle_func(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/srilankakim66/final_project/venv/lib/python3.11/site-packages/django/core/management/commands/migrate.py", line 100, in handle
self.check(databases=[database])
File "/home/srilankakim66/final_project/venv/lib/python3.11/site-packages/django/core/management/base.py", line 486, in check
all_issues = checks.run_checks(
^^^^^^^^^^^^^^^^^^
File "/home/srilankakim66/final_project/venv/lib/python3.11/site-packages/django/core/checks/registry.py", line 88, in run_checks
new_errors = check(app_configs=app_configs, databases=databases)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/srilankakim66/final_project/venv/lib/python3.11/site-packages/django/core/checks/database.py", line 13, in check_database_backends
issues.extend(conn.validation.check(**kwargs))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/srilankakim66/final_project/venv/lib/python3.11/site-packages/django/db/backends/mysql/validation.py", line 9, in check
issues.extend(self._check_sql_mode(**kwargs))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/srilankakim66/final_project/venv/lib/python3.11/site-packages/django/db/backends/mysql/validation.py", line 14, in _check_sql_mode
self.connection.sql_mode & {"STRICT_TRANS_TABLES", "STRICT_ALL_TABLES"}
^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/srilankakim66/final_project/venv/lib/python3.11/site-packages/django/utils/functional.py", line 47, in __get__
res = instance.__dict__[self.name] = self.func(instance)
^^^^^^^^^^^^^^^^^^^
File "/home/srilankakim66/final_project/venv/lib/python3.11/site-packages/django/db/backends/mysql/base.py", line 452, in sql_mode
sql_mode = self.mysql_server_data["sql_mode"]
^^^^^^^^^^^^^^^^^^^^^^
File "/home/srilankakim66/final_project/venv/lib/python3.11/site-packages/django/utils/functional.py", line 47, in __get__
res = instance.__dict__[self.name] = self.func(instance)
^^^^^^^^^^^^^^^^^^^
File "/home/srilankakim66/final_project/venv/lib/python3.11/site-packages/django/db/backends/mysql/base.py", line 408, in mysql_server_data
with self.temporary_connection() as cursor:
File "/usr/lib/python3.11/contextlib.py", line 137, in __enter__
return next(self.gen)
^^^^^^^^^^^^^^
File "/home/srilankakim66/final_project/venv/lib/python3.11/site-packages/django/db/backends/base/base.py", line 691, in temporary_connection
with self.cursor() as cursor:
^^^^^^^^^^^^^
File "/home/srilankakim66/final_project/venv/lib/python3.11/site-packages/django/utils/asyncio.py", line 26, in inner
return func(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^
File "/home/srilankakim66/final_project/venv/lib/python3.11/site-packages/django/db/backends/base/base.py", line 316, in cursor
return self._cursor()
^^^^^^^^^^^^^^
File "/home/srilankakim66/final_project/venv/lib/python3.11/site-packages/django/db/backends/base/base.py", line 292, in _cursor
self.ensure_connection()
File "/home/srilankakim66/final_project/venv/lib/python3.11/site-packages/django/utils/asyncio.py", line 26, in inner
return func(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^
File "/home/srilankakim66/final_project/venv/lib/python3.11/site-packages/django/db/backends/base/base.py", line 274, in ensure_connection
with self.wrap_database_errors:
File "/home/srilankakim66/final_project/venv/lib/python3.11/site-packages/django/db/utils.py", line 91, in __exit__
raise dj_exc_value.with_traceback(traceback) from exc_value
File "/home/srilankakim66/final_project/venv/lib/python3.11/site-packages/django/db/backends/base/base.py", line 275, in ensure_connection
self.connect()
File "/home/srilankakim66/final_project/venv/lib/python3.11/site-packages/django/utils/asyncio.py", line 26, in inner
return func(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^
File "/home/srilankakim66/final_project/venv/lib/python3.11/site-packages/django/db/backends/base/base.py", line 256, in connect
self.connection = self.get_new_connection(conn_params)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/srilankakim66/final_project/venv/lib/python3.11/site-packages/django/utils/asyncio.py", line 26, in inner
return func(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^
File "/home/srilankakim66/final_project/venv/lib/python3.11/site-packages/django/db/backends/mysql/base.py", line 256, in get_new_connection
connection = Database.connect(**conn_params)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/srilankakim66/final_project/venv/lib/python3.11/site-packages/MySQLdb/__init__.py", line 121, in Connect
return Connection(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/srilankakim66/final_project/venv/lib/python3.11/site-packages/MySQLdb/connections.py", line 195, in __init__
super().__init__(*args, **kwargs2)
django.db.utils.OperationalError: (2003, "Can't connect to MySQL server on '127.0.0.1:3306' (111)")
그래서 이게 무슨 에러지 하면서 찾아본 결과 SSH 서버와 MySQL이 연동이 되어있지 않은 문제 같았다.
그렇기에 SSH서버에 MySQL을 다운을 받아 주었다.
sudo apt-get update
sudo apt-get install mysql-server
systemctl list-units --type=service | grep -i mysql
sudo systemctl start mysql
sudo systemctl status mysql
systemctl list-units --type=service | grep -i mysql
위에 코드는 mysql이 어떠한 이름으로 다운이 되었는가에 대해서 찾아보는 코드이다.
왜냐하면 sudo systemctl start mysql의 코드에서 mysql이 간혹가다가 mysqld로 다운이 되는 경우도 생겨서 코드를 쳐서 찾아봤을 때 mysqld라고 적혀있다면 4번째, 5번째 코드를 mysql에서 mysqld로 바꿔줘야 한다.
그리고 MySQL은 설치 후에 처음으로 실행을 할때 보안관련 설정을 할 수 있는 mysql_secure_installation 스크립트를 실행하는 것을 추천한다고 한다.
sudo mysql_secure_installation
SSH를 통한 리눅스 환경에서 필자는 처음으로 MySQL을 설치 했기에 비밀번호 정책, 익명 사용자 삭제, 원격 루트 로그인 비활성화 등의 기능을 제공하는 mysql_secure_installation 스크립트를 실행했다.
- 비밀번호 정책 : Yes
- 익명 사용자 삭제 : Yes
- 원격 루트 로그인 비활성화 : No(뭔가 이것때문에 GCP와 MySQL WorkBench가 연동이 안되는 느낌이다...쎄하다 원래는 Yes로 했는데 No로 바꿔보았다.)
- test database를 지우고 그리고 그것을 승인 : No
- 마지막 부분 : Yes
Securing the MySQL server deployment.
Connecting to MySQL using a blank password.
VALIDATE PASSWORD COMPONENT can be used to test passwords
and improve security. It checks the strength of password
and allows the users to set only those passwords which are
secure enough. Would you like to setup VALIDATE PASSWORD component?
Press y|Y for Yes, any other key for No: Y
There are three levels of password validation policy:
LOW Length >= 8
MEDIUM Length >= 8, numeric, mixed case, and special characters
STRONG Length >= 8, numeric, mixed case, special characters and dictionary file
Please enter 0 = LOW, 1 = MEDIUM and 2 = STRONG: 0
Skipping password set for root as authentication with auth_socket is used by default.
If you would like to use password authentication instead, this can be done with the "ALTER_USER" command.
See https://dev.mysql.com/doc/refman/8.0/en/alter-user.html#alter-user-password-management for more information.
By default, a MySQL installation has an anonymous user,
allowing anyone to log into MySQL without having to have
a user account created for them. This is intended only for
testing, and to make the installation go a bit smoother.
You should remove them before moving into a production
environment.
Remove anonymous users? (Press y|Y for Yes, any other key for No) : Y
Success.
Normally, root should only be allowed to connect from
'localhost'. This ensures that someone cannot guess at
the root password from the network.
Disallow root login remotely? (Press y|Y for Yes, any other key for No) : No
Success.
By default, MySQL comes with a database named 'test' that
anyone can access. This is also intended only for testing,
and should be removed before moving into a production
environment.
Remove test database and access to it? (Press y|Y for Yes, any other key for No) : Y
- Dropping test database...
Success.
- Removing privileges on test database...
Success.
Reloading the privilege tables will ensure that all changes
made so far will take effect immediately.
Reload privilege tables now? (Press y|Y for Yes, any other key for No) : Y
Success.
All done!
mysql -u root -p
그리고 이제 mysql을 시작을 해보자. 필자는 분명 MySQL을 설치할 때 분명 비밀번호를 지정한것 같은데 지정이 안되어있어다. 그래서 한참 밑에 코드를 치고 비밀번호를 치라고 하는 부분을 넘어가지 못했다. 근데 그냥 엔터를 치니까 넘어가졌다.ㅠㅠㅠㅠ
여기서 MySQL의 비밀번호를 재설정하는 방법에 대해서도 적어놔야 겠다.
이것을 하던 중 또 문제를 만났다. 왜 그런지는 모르겠는데 비밀번호를 새로 설정을 해줘도 적용이 되지 않는 문제에 부딪쳤다.(수정하면서 이전의 내용을 모두 지웠다.)
진짜 MySQL 왜이렇게 속을 썩이는지 모르겠다.ㅠㅠㅠㅠ
위에서 mysql_secure_installation으로 비밀번호가 있어야 접근이 되게 끔 설정을 해주고 비밀번호를 설정한 뒤 맞게 입력을 해도 접속이 거부되는 일이 발생을 했다. 그렇기에 비밀번호를 설정했을 때 제대로 설정이 되게끔 하는 해결방법을 다시 적어둬야 겠다. @@
해결 방법은 2가지가 존재한다.
- root_user를 새로 만들기
- 비밀번호 플러그인 방식을 바꾸기 (이 방법으로 진행)
2가지가 존재 하는데 플러그인을 바꾸는 방식으로 필자는 해결을 했다. 방법을 보자.
1. 관리자 권한으로 비밀번호 없이 MySQL접속하기
sudo mysql -u root
2. 플러그인을 바꾸고 비밀번호를 다시 새롭게 설정하기 (mysql_native_password 플러그인으로 바꿈)
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '새로운 비밀번호';
3. 변경사항 적용하기
FLUSH PRIVILEGES;
4. MySQL을 종료 후 MySQL을 다시 실행
sudo systemctl restart mysql
5. 새로 설정한 비밀번호로 로그인 해보기
mysql -u root -p
위에 과정을 진행하고 접속을 해보면 비밀번호가 잘 입력되어서 접속이 되는 것을 볼 수 있다.
와 행복하다 이것때문에 시간을 너무 많이 썻다ㅠㅠㅠㅠ
위에서 필자가 보안 정책 스크립트를 설정해주었을 때 비밀번호 보안 정책을 잘못 설정했나 계속 해서 비밀번호가 보안정책에 위배된다는 에러가 떳었다. 그렇기에 보안 정책을 바꾸는 방법에 대해서도 적어 놔야지
1. 비밀번호의 정책을 확인한다.(mysql을 켜고 작성)
SHOW VARIABLES LIKE 'validate_password%';
여기서 validate_password.policy를 확인해야 한다. LOW, MEDIUM, STRONG인지 확인을 한다.
2. 비밀번호 정책 변경하기
SET GLOBAL validate_password.policy=LOW;
일단은 가장 낮은 LOW로 정책을 변경해준다.
또한 비밀번호의 최소 길이를 변경하고 싶다면, 아래 쿼리를 작성해준다.
SET GLOBAL validate_password.length = 8;
3. 위에 작성해 놓은 비밀번호를 다시 설정해주는 방법을 그대로 따라가서 비밀번호가 성공적으로 바뀌는지 확인한다.
4. 변경 사항을 적용하기 위해 MySQL서버를 재시작해준다.
sudo systemctl restart mysql
참고한 블로그
https://10web.io/blog/mysql-error-1698/
How to Solve MySQL Error 1698: A Detailed Guide
Let's learn what is MySQL error 1698 (28000), discover the reasons behind it and discuss how you can solve it effectively.
10web.io
근데 이래도 계속해서 django와 연동된 MySQL WorkBench가 리눅스 서버에서는 연동이 안되었다.
계속해서 찾아보니 GCP와 MySQL WorkBench를 연동하는 방법이 있는 블로그를 찾았다. 오늘은 너무 피곤해서 자고 일어나서 다시 한번 실행을 해보아야겠다. 과연 이것이 내가 django와 연동을 해놓은 MySQL WorkBench와 GCP의 VM머신으로 만든 리눅스 서버에 MySQL WorkBench와 다같이 연동이 되는지는 확실히 잘 모르겠다.
GCP 인스턴스에 MYSQL 설치하고 WORKBENCH 연결하기
GCP Compute Engine VM안에 MYSQL을 설치하고 workbench 로 연결하기
velog.io
그래도 쭉 찾아서 다시 해봐야겠다.
2024/05/13 @@@@
'프로젝트' 카테고리의 다른 글
파이널 프로젝트-기획 (0) | 2024.05.23 |
---|---|
GCP Ubuntu의 python버전을 로컬 python 버전에 맞추고 MySQL Workbench 연동하기(mysqlclient import 에러 해결) (0) | 2024.05.14 |
GCP의 ubuntu와 로컬에서의 버전맞추기(두번째 트러블 슈팅 해결) (0) | 2024.05.13 |
GCP와 MySQL WorkBench연동하기(두번째 트러블 슈팅 계속...) (0) | 2024.05.13 |
django GCP로 배포 중 트러블 슈팅(Ubuntu운영체제) (2) | 2024.05.11 |