Docs Home → 애플리케이션 개발 → Python 드라이버 → PyMongo
문제 해결
이 페이지에서는 MongoDB와 함께 PyMongo를 사용하는 동안 발생하는 일반적인 문제에 대한 솔루션을 찾을 수 있습니다.
연결
MongoDB Server, 유선 버전 X, PyMongo Y가 필요하다고 보고
MongoDB Server v3.4 이하 버전에 연결하려고 하면 PyMongo에서 다음 오류가 발생할 수 있습니다.
pymongo.errors.ConfigurationError: Server at localhost:27017 reports wire version 5, but this version of PyMongo requires at least 6 (MongoDB 3.6).
이는 드라이버 버전이 연결하려는 서버에 비해 너무 최신 버전일 때 발생합니다. 이 문제를 해결하려면 MongoDB deployment를 v3.6 이상으로 업그레이드하거나 MongoDB Server v2.6 이상을 지원하는 PyMongo v3.x로 다운그레이드합니다.
자동 재연결
AutoReconnect
예외는 페일오버 가 발생했음을 나타냅니다. 이는 PyMongo가 복제본 세트의 원래 프라이머리 멤버에 대한 연결을 잃었고 마지막 작업이 실패했을 수 있음을 의미합니다.
이 오류가 발생하면 PyMongo는 후속 작업을 위해 자동으로 새 프라이머리 멤버를 찾으려고 시도합니다. 오류를 처리하려면 애플리케이션에서 다음 조치 중 하나를 수행해야 합니다.
실패했을 수 있는 작업 재시도
작업이 실패했을 수 있다는 점을 이해하고 계속 실행합니다.
중요
PyMongo는 복제본 세트가 새 프라이머리 멤버를 선택할 때까지 모든 작업에서 AutoReconnect
오류를 발생시킵니다.
터널링을 사용하여 PyMongo에서 MongoDB에 액세스할 때 시간 초과
SSH 터널을 통해 MongoDB 복제본 세트에 연결하려고 하면 다음 오류가 발생합니다.
File "/Library/Python/2.7/site-packages/pymongo/collection.py", line 1560, in count return self._count(cmd, collation, session) File "/Library/Python/2.7/site-packages/pymongo/collection.py", line 1504, in _count with self._socket_for_reads() as (connection, slave_ok): File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/contextlib.py", line 17, in __enter__ return self.gen.next() File "/Library/Python/2.7/site-packages/pymongo/mongo_client.py", line 982, in _socket_for_reads server = topology.select_server(read_preference) File "/Library/Python/2.7/site-packages/pymongo/topology.py", line 224, in select_server address)) File "/Library/Python/2.7/site-packages/pymongo/topology.py", line 183, in select_servers selector, server_timeout, address) File "/Library/Python/2.7/site-packages/pymongo/topology.py", line 199, in _select_servers_loop self._error_message(selector)) pymongo.errors.ServerSelectionTimeoutError: localhost:27017: timed out
이는 PyMongo가 다른 복제본 세트 멤버의 주소와 포트가 포함된 isMaster
명령의 응답을 사용하여 복제본 세트 멤버를 검색하기 때문에 발생합니다. 그러나 SSH 터널을 통해 이러한 주소와 포트에 액세스할 수는 없습니다.
대신 SSH 터널링과 함께 directConnection=True
옵션을 사용하여 단일 MongoDB 노드에 직접 연결할 수 있습니다.
읽기 및 쓰기 작업
AutoReconnect
오류
읽기 설정에 tag-sets
을(를) 지정하고 MongoDB가 지정된 태그를 가진 복제본 세트 멤버를 찾을 수 없는 경우 이 오류가 발생합니다. 이 오류를 방지하려면 태그 세트 목록 끝에 빈 사전({}
)을 포함하세요. 이는 일치하는 태그를 찾을 수 없는 경우 읽기 참조 모드와 일치하는 모든 멤버에서 읽도록 PyMongo에 지시합니다.
DeprecationWarning: 카운트는 더 이상 사용되지 않습니다.
PyMongo는 더 이상 count()
메서드를 지원하지 않습니다. 대신 Collection
클래스의 count_documents()
메서드를 사용합니다.
중요
count_documents()
메서드는 Collection
클래스에 속합니다. Cursor.count_documents()
를 호출하려고 하면 PyMongo에서 다음 오류가 발생합니다.
Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'Cursor' object has no attribute 'count'
MongoClient 구성 오류 실패
잘못된 키워드 인수 이름을 제공하면 드라이버에서 이 오류가 발생합니다.
지정한 키워드 인수가 존재하고 철자가 올바른지 확인합니다.
웹 애플리케이션에서 ObjectId로 문서를 쿼리할 때 결과가 표시되지 않음
웹 애플리케이션에서는 다음 코드 예제와 같이 URL에 문서의 ObjectId를 인코딩하는 것이 일반적입니다.
"/posts/50b3bda58a02fb9a84d8991e"
웹 프레임워크는 ObjectId 의 부분을 URL 요청 핸들러에 로 string 전달합니다. 문자열을 find_one()
메서드에 전달하기 전에 string 을 ObjectId
인스턴스로 변환해야 합니다.
다음 코드 예시는 Flask 에서 이 변환을 수행하는 방법을 보여줍니다. 애플리케이션. 이 프로세스는 다른 웹 프레임워크도 비슷합니다.
from pymongo import MongoClient from bson.objectid import ObjectId from flask import Flask, render_template client = MongoClient() app = Flask(__name__) def show_post(_id): # NOTE!: converting _id from string to ObjectId before passing to find_one post = client.db.posts.find_one({'_id': ObjectId(_id)}) return render_template('post.html', post=post) if __name__ == "__main__": app.run()
쿼리는 shell 에서는 작동하지만 PyMongo에서는 작동하지 않음
항상 첫 번째인 _id
필드 이후에는 BSON 문서에서 키-값 쌍이 임의의 순서로 배치될 수 있습니다. mongo
shell 은 다음 코드 예제의 "b" 및 "a" 필드에 표시된 대로 데이터를 읽고 쓸 때 키 순서를 유지합니다.
// mongo shell db.collection.insertOne( { "_id" : 1, "subdocument" : { "b" : 1, "a" : 1 } } ) // Returns: WriteResult({ "nInserted" : 1 }) db.collection.findOne() // Returns: { "_id" : 1, "subdocument" : { "b" : 1, "a" : 1 } }
PyMongo는 기본적으로 BSON 문서를 Python 사전으로 나타내며, 사전의 키 순서는 정의되지 않습니다. Python에서 "a" 키로 먼저 선언된 딕셔너리는 "b" 키를 먼저 선언한 딕셔너리와 동일합니다. 다음 예에서 키는 print
문의 순서에 관계없이 동일한 순서로 표시됩니다.
print({'a': 1.0, 'b': 1.0}) # Returns: {'a': 1.0, 'b': 1.0} print({'b': 1.0, 'a': 1.0}) # Returns: {'a': 1.0, 'b': 1.0}
마찬가지로 Python 사전은 BSON에 저장된 순서대로 키를 표시하지 않을 수 있습니다. 다음 예는 앞의 예에서 삽입한 문서를 인쇄한 결과를 보여줍니다.
print(collection.find_one()) # Returns: {'_id': 1.0, 'subdocument': {'a': 1.0, 'b': 1.0}}
BSON을 읽을 때 키 순서를 유지하려면 키 순서를 기억하는 딕셔너리인 SON
클래스를 사용합니다.
다음 코드 예시에서는 SON
클래스를 사용하도록 구성된 컬렉션을 만드는 방법을 보여 줍니다.
from bson import CodecOptions, SON opts = CodecOptions(document_class=SON) CodecOptions(document_class=...SON..., tz_aware=False, uuid_representation=UuidRepresentation.UNSPECIFIED, unicode_decode_error_handler='strict', tzinfo=None, type_registry=TypeRegistry(type_codecs=[], fallback_encoder=None), datetime_conversion=DatetimeConversion.DATETIME) collection_son = collection.with_options(codec_options=opts)
앞의 하위 문서를 찾으면 드라이버는 SON
객체를 사용하여 쿼리 결과를 나타내며 키 순서를 유지합니다.
print(collection_son.find_one())
SON([('_id', 1.0), ('subdocument', SON([('b', 1.0), ('a', 1.0)]))])
이제 하위 문서의 실제 스토리지 레이아웃을 볼 수 있습니다: 'b'가 'a' 앞에 있습니다.
Python 딕셔너리의 키 순서는 정의되어 있지 않기 때문에 BSON으로 직렬화되는 방식을 예측할 수 없습니다. 그러나 MongoDB는 키의 순서가 동일한 경우에만 하위 문서를 동일한 것으로 간주합니다. Python 사전을 사용하여 하위 문서를 쿼리하는 경우 일치하지 않을 수 있습니다.
collection.find_one({'subdocument': {'b': 1.0, 'a': 1.0}}) is None
True
Python은 두 사전을 동일하게 간주하므로 쿼리에서 키 순서를 바꿔도 차이가 없습니다.
collection.find_one({'subdocument': {'b': 1.0, 'a': 1.0}}) is None
True
이 문제는 두 가지 방법으로 해결할 수 있습니다. 먼저 하위 문서를 필드별로 일치시킬 수 있습니다.
collection.find_one({'subdocument.a': 1.0, 'subdocument.b': 1.0})
{'_id': 1.0, 'subdocument': {'a': 1.0, 'b': 1.0}}
쿼리는 Python에서 지정하는 순서나 BSON에서 저장되는 순서에 관계없이 'b'가 1.0 이고 'b'가 1.0 인 모든 하위 문서와 일치합니다. 이 쿼리는 이제 'a' 및 'b' 외에 추가 키가 있는 하위 문서도 일치하지만, 이전 쿼리에서는 정확히 일치해야 합니다.
두 번째 해결책은 ~bson.son.SON
객체를 사용하여 키 순서를 지정하는 것입니다.
query = {'subdocument': SON([('b', 1.0), ('a', 1.0)])} collection.find_one(query)
{'_id': 1.0, 'subdocument': {'a': 1.0, 'b': 1.0}}
드라이버는 ~bson.son.SON
를 BSON으로 직렬화하고 쿼리로 사용할 때 생성할 때 사용하는 키 순서를 유지합니다. 따라서 컬렉션의 하위 문서와 정확히 일치하는 하위 문서를 만들 수 있습니다.
참고
하위 문서 일치에 대한 자세한 내용은 MongoDB Server 설명서의 내장된/중첩 문서에 대한 쿼리 가이드를 참조하세요.
Cursors
'Cursor' 객체에 '_Cursor__killed' 속성이 없습니다.
PyMongo v3.8 이전 버전에서는 Cursor
생성자에 잘못된 인수를 제공하면 TypeError
및 AttributeError
가 발생합니다. AttributeError
는 관련이 없지만 TypeError
에는 다음 예제와 같이 디버깅 정보가 포함되어 있습니다.
Exception ignored in: <function Cursor.__del__ at 0x1048129d8> ... AttributeError: 'Cursor' object has no attribute '_Cursor__killed' ... TypeError: __init__() got an unexpected keyword argument '<argument>'
이 문제를 해결하려면 올바른 키워드 인수를 제공했는지 확인하세요. 관련 없는 오류를 제거하면 PyMongo v3.9 이상으로 업그레이드할 수도 있습니다.
" 서버에서 CursorNotFound 커서 ID가 유효하지 않습니다"
MongoDB의 커서는 아무런 작업도 수행되지 않은 상태에서 오랫동안 열려 있는 경우 서버에서 시간 초과가 발생할 수 있습니다. 이로 인해 커서를 반복하려고 할 때 CursorNotFound
예외가 발생할 수 있습니다.
프로젝션
'포함 프로젝션의 <field> 필드에 대해 제외를 수행할 수 없음'
단일 프로젝션에 필드를 포함 및 제외하려고 하면 드라이버는 이 메시지와 함께 OperationFailure
를 반환합니다. 프로젝션이 포함할 필드 또는 제외할 필드만 지정하는지 확인합니다.
Indexes
DuplicateKeyException
고유 인덱스 를 위반하는 중복 값을 저장하는 쓰기 작업을 수행하면 드라이버에서 DuplicateKeyException
가 발생하고 MongoDB에서 다음과 유사한 오류가 발생합니다.
E11000 duplicate key error index
데이터 형식
ValueError: 네이티브 uuid.UUID를 UuidRepresentation.UNSPECIFIED로 인코딩할 수 없습니다.
이 오류는 다음 코드 예시와 같이 UUID 표현이 UNSPECIFIED
일 때 네이티브 UUID
객체를 Binary
객체로 인코딩하려고 시도할 때 발생합니다.
unspecified_collection.insert_one({'_id': 'bar', 'uuid': uuid4()}) Traceback (most recent call last): ... ValueError: cannot encode native uuid.UUID with UuidRepresentation.UNSPECIFIED. UUIDs can be manually converted to bson.Binary instances using bson.Binary.from_uuid() or a different UuidRepresentation can be configured. See the documentation for UuidRepresentation for more information.
대신 다음 예와 같이 Binary.from_uuid()
메서드를 사용하여 네이티브 UUID를 Binary
객체로 명시적으로 변환해야 합니다.
explicit_binary = Binary.from_uuid(uuid4(), UuidRepresentation.STANDARD) unspec_collection.insert_one({'_id': 'bar', 'uuid': explicit_binary})
다른 언어 드라이버에 의해 저장된 날짜 디코딩 시 OverflowError가 발생합니다.
PyMongo는 BSON datetime
값을 Python의 datetime.datetime
클래스 인스턴스로 디코딩합니다. datetime.datetime
의 인스턴스는 datetime.MINYEAR
(1)에서 datetime.MAXYEAR
(9999) 사이의 연도로 제한됩니다. 일부 MongoDB 드라이버는 datetime.datetime
에서 지원하는 것보다 훨씬 큰 연도 값으로 BSON 날짜/시간을 저장할 수 있습니다.
이 문제를 해결하는 방법에는 몇 가지가 있습니다. PyMongo 4.3 부터 bson.decode
는 네 가지 방법 중 하나로 BSON datetime
값을 디코딩할 수 있습니다. ~bson.codec_options.CodecOptions
의 datetime_conversion
매개 변수를 사용하여 변환 방법을 지정할 수 있습니다.
기본 변환 옵션은 ~bson.codec_options.DatetimeConversion.DATETIME
이며, 이 값은 datetime.datetime
로 디코딩을 시도하여 범위를 벗어난 날짜에 대해 ~builtin.OverflowError
이(가) 발생하도록 합니다. ~bson.codec_options.DatetimeConversion.DATETIME_AUTO
은 표현이 범위를 벗어날 때 대신 ~bson.datetime_ms.DatetimeMS
를 반환하고 이전과 같이 ~datetime.datetime
객체를 반환하도록 이 동작을 변경합니다.
from datetime import datetime from bson.datetime_ms import DatetimeMS from bson.codec_options import DatetimeConversion from pymongo import MongoClient client = MongoClient(datetime_conversion=DatetimeConversion.DATETIME_AUTO) client.db.collection.insert_one({"x": datetime(1970, 1, 1)}) client.db.collection.insert_one({"x": DatetimeMS(2**62)}) for x in client.db.collection.find(): print(x)
{'_id': ObjectId('...'), 'x': datetime.datetime(1970, 1, 1, 0, 0)} {'_id': ObjectId('...'), 'x': DatetimeMS(4611686018427387904)}
다른 옵션은 DatetimeConversion 에 대한 API 설명서를 참조하세요. 클래스.
datetime_conversion
설정을 포함하지 않는 또 다른 옵션은 ~datetime.datetime
에서 지원하는 범위를 벗어나는 문서 값을 필터링하는 것입니다.
from datetime import datetime coll = client.test.dates cur = coll.find({'dt': {'$gte': datetime.min, '$lte': datetime.max}})
datetime
값이 필요하지 않은 경우 해당 필드만 필터링할 수 있습니다.
cur = coll.find({}, projection={'dt': False})
TLS
CAERTIFICATE_VERIFY_FAILED
다음과 유사한 오류 메시지는 OpenSSL이 서버의 인증서를 확인할 수 없음을 의미합니다.
[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed
이는 OpenSSL이 시스템의 루트 인증서에 액세스할 수 없거나 인증서가 최신 버전이 아니기 때문에 자주 발생합니다.
Linux를 사용하는 경우 Linux 공급업체로부터 최신 루트 인증서 업데이트를 설치했는지 확인합니다.
macOS를 사용하고 python.org에서 다운로드한 Python v3.7 이상을 실행하는 경우, 다음 명령을 실행하여 루트 인증서를 설치합니다.
open "/Applications/Python <YOUR PYTHON VERSION>/Install Certificates.command"
팁
이 문제에 대한 자세한 내용은 Python 문제 29065 를 참조하세요.
이식 가능한 pypy를 사용하는 경우 환경 변수를 설정하여 OpenSSL에 루트 인증서를 찾을 수 있는 위치를 알려야 할 수 있습니다. 다음 코드 예시에서는 certifi 모듈 을 설치하는 방법을 보여줍니다. PyPi에서 SSL_CERT_FILE
환경 변수를 내보냅니다.
$ pypy -m pip install certifi $ export SSL_CERT_FILE=$(pypy -c "import certifi; print(certifi.where())")
팁
이 문제에 대한 자세한 내용은 portable-pypy 문제 15 를 참조하세요.
TLSV1_ALERT_PROTOCOL_VERSION
다음과 유사한 오류 메시지는 Python에서 사용하는 OpenSSL 버전이 서버에 연결할 수 있을 만큼 새로운 TLS 프로토콜을 지원하지 않음을 의미합니다.
[SSL: TLSV1_ALERT_PROTOCOL_VERSION] tlsv1 alert protocol version
업계 모범 사례는 일부 MongoDB 배포에서 이전 TLS 프로토콜을 비활성화할 것을 권장하며 일부 규정에서는 요구하고 있습니다. 일부 배포는 TLS 1.0 을 비활성화할 수 있고, 다른 배포는 TLS 1.0 및 TLS 1.1 을 비활성화할 수 있습니다.
PyMongo가 최신 TLS 버전을 사용하기 위해 애플리케이션을 변경할 필요는 없지만, 일부 운영 체제 버전은 이를 지원할 만큼 새로운 OpenSSL 버전을 제공하지 않을 수 있습니다.
macOS v10.12 을 사용하는 경우 (High Sierra) 이하 버전인 경우, python.org에서 Python을 설치합니다. 홈브루, macports 또는 유사한 소스.
Linux 또는 macOS가 아닌 다른 Unix를 사용하는 경우 다음 명령을 사용하여 OpenSSL 버전을 확인합니다.
openssl version
앞의 명령이 1.0.1 보다 작은 버전 번호를 표시하는 경우, TLS 1.1 이상에 대한 지원은 제공되지 않습니다. 최신 버전으로 업그레이드하거나 OS 공급업체에 솔루션을 문의하세요.
Python 인터프리터의 TLS 버전을 확인하려면 requests
모듈을 설치하고 다음 코드를 실행합니다.
python -c "import requests; print(requests.get('https://www.howsmyssl.com/a/check', verify=False).json()['tls_version'])"
TLS 1.1 이상이 표시됩니다.
잘못된 상태 응답
다음과 유사한 오류 메시지는 인증서 해지 확인에 실패했음을 의미합니다.
[('SSL routines', 'tls_process_initial_server_flight', 'invalid status response')]
자세한 내용은 이 가이드의 OCSP 섹션을 참조하세요.
SSLV3_ALERT_HANDSHAKE_FAILURE
Python v3.10 이상을 v4.0 이전의 MongoDB 버전과 함께 사용하는 경우, 다음 메시지와 유사한 오류가 표시될 수 있습니다.
SSL handshake failed: localhost:27017: [SSL: SSLV3_ALERT_HANDSHAKE_FAILURE] sslv3 alert handshake failure (_ssl.c:997) SSL handshake failed: localhost:27017: EOF occurred in violation of protocol (_ssl.c:997)
MongoDB Server 로그에 다음 오류가 표시될 수도 있습니다.
2021-06-30T21:22:44.917+0100 E NETWORK [conn16] SSL: error:1408A0C1:SSL routines:ssl3_get_client_hello:no shared cipher
Python v 의 ssl 모듈에 대한 변경 사항3.10 v4 이전의 MongoDB 버전과 호환되지 않을 수 있습니다.0. 이 문제를 해결하려면 다음 단계 중 하나 이상을 시도해 보세요.
Python을 v3.9 이하 버전으로 다운그레이드
MongoDB Server를 v4.2 이상으로 업그레이드
PyOpenSSL을 사용하는 OCSP 옵션을 사용하여 PyMongo를 설치합니다.
클라이언트 측 작업 시간 초과
ServerSelectionTimeoutError
이 오류는 클라이언트가 지정된 제한 시간 내에 작업을 실행할 수 있는 서버를 찾을 수 없음을 나타냅니다.
pymongo.errors.ServerSelectionTimeoutError: No servers found yet, Timeout: -0.00202266700216569s, Topology Description: <TopologyDescription id: 63698e87cebfd22ab1bd2ae0, topology_type: Unknown, servers: [<ServerDescription ('localhost', 27017) server_type: Unknown, rtt: None>]>
NetworkTimeout
이 오류는 클라이언트가 지정된 제한 시간 내에 연결을 설정할 수 없거나 작업이 전송되었지만 서버가 제때 응답하지 않았음을 나타냅니다.
pymongo.errors.NetworkTimeout: localhost:27017: timed out
ExecutionTimeout
이 오류는 지정된 제한 시간을 초과하여 서버가 작업을 취소했음을 나타낼 수 있습니다. PyMongo에서 이 예외가 발생하더라도 서버에서 작업이 부분적으로 완료되었을 수 있습니다.
pymongo.errors.ExecutionTimeout: operation exceeded time limit, full error: {'ok': 0.0, 'errmsg': 'operation exceeded time limit', 'code': 50, 'codeName': 'MaxTimeMSExpired'}
또한 지정된 제한 시간 내에 작업을 완료할 수 없어 클라이언트가 작업을 취소했음을 나타낼 수도 있습니다.
pymongo.errors.ExecutionTimeout: operation would exceed time limit, remaining timeout:0.00196 <= network round trip time:0.00427
WTimeoutError
이 오류는 서버가 지정된 제한 시간 내에 지정된 쓰기 고려를 따라 요청된 쓰기 작업을 완료하지 못했음을 나타냅니다.
pymongo.errors.WTimeoutError: operation exceeded time limit, full error: {'code': 50, 'codeName': 'MaxTimeMSExpired', 'errmsg': 'operation exceeded time limit', 'errInfo': {'writeConcern': {'w': 1, 'wtimeout': 0}}}
BulkWriteError
이 오류는 서버가 지정된 제한 시간 내에 지정된 쓰기 고려에 따라 insert_many()
또는 bulk_write()
메서드를 완료하지 못했음을 나타냅니다.
pymongo.errors.BulkWriteError: batch op errors occurred, full error: {'writeErrors': [], 'writeConcernErrors': [{'code': 50, 'codeName': 'MaxTimeMSExpired', 'errmsg': 'operation exceeded time limit', 'errInfo': {'writeConcern': {'w': 1, 'wtimeout': 0}}}], 'nInserted': 2, 'nUpserted': 0, 'nMatched': 0, 'nModified': 0, 'nRemoved': 0, 'upserted': []}
포크 프로세스
프로세스 포크로 인해 교착 상태 발생
MongoClient
인스턴스는 연결된 서버 모니터링과 같은 백그라운드 작업을 실행하기 위해 여러 스레드를 생성합니다. 이러한 스레드는 클래스의 인스턴스로 보호되는 상태를 공유하며, 이 인스턴스는 자체적 threading.Lock
으로 포크 세이프가 아닙니다 . . PyMongo에는 threading.Lock
클래스 또는 뮤텍스를 사용하는 다른 멀티스레드 코드와 동일한 제한이 적용됩니다.
이러한 제한 사항 중 하나는 fork()
메서드를 호출한 후 잠금이 사용할 수 없게 된다는 것입니다. fork()
이 실행되면 드라이버는 상위 프로세스의 모든 잠금을 상위 프로세스와 동일한 상태로 하위 프로세스에 복사합니다. 상위 프로세스에 잠겨 있으면 하위 프로세스에도 잠깁니다. fork()
가 만든 하위 프로세스에는 스레드가 하나만 있으므로 상위 프로세스의 다른 스레드가 만든 잠금은 하위 프로세스에서 해제되지 않습니다. 다음에 자식 프로세스가 이러한 잠금 중 하나를 얻으려고 시도하면 교착 상태가 발생합니다.
PyMongo 버전 4.3 부터 os.fork()
메서드를 호출한 후 드라이버는 os.register_at_fork()
메서드를 사용하여 하위 프로세스에서 잠금 및 기타 공유 상태를 재설정합니다. 이렇게 하면 교착 상태가 발생할 가능성이 줄어들지만, PyMongo는 OpenSSL 을 포함한 멀티스레드 애플리케이션에서 포크3 세이프가 아닌 라이브러리에 의존합니다. 및 getaddrinfo( ). 따라서 여전히 교착 상태가 발생할 수 있습니다.
fork(2) 에 대한 Linux 매뉴얼 페이지 또한 다음과 같은 제한 사항을 적용합니다.
fork()
멀티스레드 프로그램에서 이후에는 자식이 비동기 신호 안전 함수만 안전하게 호출할 수 있습니다(signal-safety(7 참조). )를 호출할 때까지 execve(2)를 호출합니다.
PyMongo는 비동기 신호에 안전 하지 않은 함수를 사용하기 때문에 하위 프로세스에서 실행할 때 교착 상태 또는 충돌이 발생할 수 있습니다.
팁
하위 프로세스의 교착 상태에 대한 예는 PYTHON-3406 을(를) 참조하세요. Jira에서.
가 6721 있는 멀티스레드 컨텍스트에서 Python 잠금으로 인해 발생하는 문제에 대한 자세한 내용은 fork()
문제 를 참조하세요. Python 이슈 트래커에서.