Read an entire "mysql packet" in its entirety from the network and return a MysqlPacket type that represents the results. :raise OperationalError: If the connection to the MySQL server is lost. :raise InternalError: If the packet sequence number is wrong.
(self, packet_type=MysqlPacket)
| 759 | self._next_seq_id = (self._next_seq_id + 1) % 256 |
| 760 | |
| 761 | def _read_packet(self, packet_type=MysqlPacket): |
| 762 | """Read an entire "mysql packet" in its entirety from the network |
| 763 | and return a MysqlPacket type that represents the results. |
| 764 | |
| 765 | :raise OperationalError: If the connection to the MySQL server is lost. |
| 766 | :raise InternalError: If the packet sequence number is wrong. |
| 767 | """ |
| 768 | # Although `socket.settimeout()` may appear fast, it temporarily releases |
| 769 | # the GIL, which can hurt performance in multithreaded applications. |
| 770 | # Avoid calling it repeatedly at high frequency. |
| 771 | if self._current_timeout != self._read_timeout: |
| 772 | self._sock.settimeout(self._read_timeout) |
| 773 | self._current_timeout = self._read_timeout |
| 774 | |
| 775 | buff = [] |
| 776 | while True: |
| 777 | packet_header = self._read_bytes(4) |
| 778 | # if DEBUG: dump_packet(packet_header) |
| 779 | |
| 780 | btrl, btrh, packet_number = struct.unpack("<HBB", packet_header) |
| 781 | bytes_to_read = btrl + (btrh << 16) |
| 782 | if packet_number != self._next_seq_id: |
| 783 | self._force_close() |
| 784 | if packet_number == 0: |
| 785 | # MariaDB sends error packet with seqno==0 when shutdown |
| 786 | raise err.OperationalError( |
| 787 | CR.CR_SERVER_LOST, |
| 788 | "Lost connection to MySQL server during query", |
| 789 | ) |
| 790 | raise err.InternalError( |
| 791 | "Packet sequence number wrong - got %d expected %d" |
| 792 | % (packet_number, self._next_seq_id) |
| 793 | ) |
| 794 | self._next_seq_id = (self._next_seq_id + 1) % 256 |
| 795 | |
| 796 | recv_data = self._read_bytes(bytes_to_read) |
| 797 | if DEBUG: |
| 798 | dump_packet(recv_data) |
| 799 | buff.append(recv_data) |
| 800 | # https://dev.mysql.com/doc/internals/en/sending-more-than-16mbyte.html |
| 801 | if bytes_to_read < MAX_PACKET_LEN: |
| 802 | break |
| 803 | |
| 804 | packet = packet_type(b"".join(buff), self.encoding) |
| 805 | if packet.is_error_packet(): |
| 806 | if self._result is not None and self._result.unbuffered_active is True: |
| 807 | self._result.unbuffered_active = False |
| 808 | packet.raise_for_error() |
| 809 | return packet |
| 810 | |
| 811 | def _read_bytes(self, num_bytes): |
| 812 | # NOTE: caller should call self._sock.settimeout(self._read_timeout) |