Khi cập nhật một số lượng lớn bản ghi trong cơ sở dữ liệu OLTP, chẳng hạn như MySQL, bạn phải lưu ý về việc khóa bản ghi. Nếu những bản ghi đó bị khóa, chúng sẽ không thể chỉnh sửa [cập nhật hoặc xóa] bởi các giao dịch khác trên cơ sở dữ liệu của bạn. Một phương pháp phổ biến được sử dụng để cập nhật một số lượng lớn bản ghi là chạy nhiều bản cập nhật nhỏ hơn theo đợt. Bằng cách này, chỉ những bản ghi đang được cập nhật tại bất kỳ thời điểm nào mới bị khóa
Nếu bạn đang tự hỏi
Làm cách nào để cập nhật hàng triệu bản ghi mà không ảnh hưởng đáng kể đến trải nghiệm người dùng?
Lệnh cập nhật khóa bản ghi như thế nào?
Sau đó, bài viết này là dành cho bạn. Lưu ý rằng đây không phải là cách duy nhất. Có các cách tiếp cận khác như hoán đổi bảng, chạy bản cập nhật tiêu chuẩn tùy thuộc vào mức độ cô lập giao dịch của bạn, v.v. Việc sử dụng các phương pháp này phụ thuộc vào trường hợp sử dụng của bạn. Đối với trường hợp sử dụng của chúng tôi, giả sử chúng tôi đang cập nhật bảng người dùng, nếu bị khóa trong một khoảng thời gian đáng kể [giả sử > 10 giây], có thể ảnh hưởng đáng kể đến trải nghiệm người dùng của chúng tôi và không lý tưởng
Cài đặtChúng tôi sẽ sử dụng docker để chạy thư viện
#!/usr/bin/env python3
import argparse
import random
from faker import Faker
def gen_user_data[file_name: str, num_records: int, seed: int = 1] -> None:
fake = Faker["en_US"]
with open[file_name, "w"] as file1:
for i in range[1, num_records + 1]:
file1.write[
f"{seed + i},{fake.name[]},{random.randint[0,1]},{fake.state[]},{fake.country[]}\n"
]
if __name__ == "__main__":
parser = argparse.ArgumentParser[description="Generate some fake data"]
parser.add_argument[
"--file-name",
type=str,
default="fake_user.csv",
help="file name to store fake data",
]
parser.add_argument[
"--num-records", type=int, default=100, help="Num of records to generate"
]
parser.add_argument["--seed", type=int, default=0, help="seed"]
args = parser.parse_args[]
gen_user_data[
file_name=args.file_name, num_records=args.num_records, seed=args.seed
]
3 container và python #!/usr/bin/env python3
import argparse
import random
from faker import Faker
def gen_user_data[file_name: str, num_records: int, seed: int = 1] -> None:
fake = Faker["en_US"]
with open[file_name, "w"] as file1:
for i in range[1, num_records + 1]:
file1.write[
f"{seed + i},{fake.name[]},{random.randint[0,1]},{fake.state[]},{fake.country[]}\n"
]
if __name__ == "__main__":
parser = argparse.ArgumentParser[description="Generate some fake data"]
parser.add_argument[
"--file-name",
type=str,
default="fake_user.csv",
help="file name to store fake data",
]
parser.add_argument[
"--num-records", type=int, default=100, help="Num of records to generate"
]
parser.add_argument["--seed", type=int, default=0, help="seed"]
args = parser.parse_args[]
gen_user_data[
file_name=args.file_name, num_records=args.num_records, seed=args.seed
]
4 để tạo dữ liệu giả- người đóng tàu
- con trăn
- kẻ giả mạo
Hãy thiết lập một thư mục dự án và tạo một số dữ liệu người dùng giả mạo
mkdir lock_update && cd lock_update
Tạo tập lệnh python tạo dữ liệu giả có tên
#!/usr/bin/env python3
import argparse
import random
from faker import Faker
def gen_user_data[file_name: str, num_records: int, seed: int = 1] -> None:
fake = Faker["en_US"]
with open[file_name, "w"] as file1:
for i in range[1, num_records + 1]:
file1.write[
f"{seed + i},{fake.name[]},{random.randint[0,1]},{fake.state[]},{fake.country[]}\n"
]
if __name__ == "__main__":
parser = argparse.ArgumentParser[description="Generate some fake data"]
parser.add_argument[
"--file-name",
type=str,
default="fake_user.csv",
help="file name to store fake data",
]
parser.add_argument[
"--num-records", type=int, default=100, help="Num of records to generate"
]
parser.add_argument["--seed", type=int, default=0, help="seed"]
args = parser.parse_args[]
gen_user_data[
file_name=args.file_name, num_records=args.num_records, seed=args.seed
]
5#!/usr/bin/env python3
import argparse
import random
from faker import Faker
def gen_user_data[file_name: str, num_records: int, seed: int = 1] -> None:
fake = Faker["en_US"]
with open[file_name, "w"] as file1:
for i in range[1, num_records + 1]:
file1.write[
f"{seed + i},{fake.name[]},{random.randint[0,1]},{fake.state[]},{fake.country[]}\n"
]
if __name__ == "__main__":
parser = argparse.ArgumentParser[description="Generate some fake data"]
parser.add_argument[
"--file-name",
type=str,
default="fake_user.csv",
help="file name to store fake data",
]
parser.add_argument[
"--num-records", type=int, default=100, help="Num of records to generate"
]
parser.add_argument["--seed", type=int, default=0, help="seed"]
args = parser.parse_args[]
gen_user_data[
file_name=args.file_name, num_records=args.num_records, seed=args.seed
]
Tập lệnh
#!/usr/bin/env python3
import argparse
import random
from faker import Faker
def gen_user_data[file_name: str, num_records: int, seed: int = 1] -> None:
fake = Faker["en_US"]
with open[file_name, "w"] as file1:
for i in range[1, num_records + 1]:
file1.write[
f"{seed + i},{fake.name[]},{random.randint[0,1]},{fake.state[]},{fake.country[]}\n"
]
if __name__ == "__main__":
parser = argparse.ArgumentParser[description="Generate some fake data"]
parser.add_argument[
"--file-name",
type=str,
default="fake_user.csv",
help="file name to store fake data",
]
parser.add_argument[
"--num-records", type=int, default=100, help="Num of records to generate"
]
parser.add_argument["--seed", type=int, default=0, help="seed"]
args = parser.parse_args[]
gen_user_data[
file_name=args.file_name, num_records=args.num_records, seed=args.seed
]
5 tạo dữ liệu giả có định dạng #!/usr/bin/env python3
import argparse
import random
from faker import Faker
def gen_user_data[file_name: str, num_records: int, seed: int = 1] -> None:
fake = Faker["en_US"]
with open[file_name, "w"] as file1:
for i in range[1, num_records + 1]:
file1.write[
f"{seed + i},{fake.name[]},{random.randint[0,1]},{fake.state[]},{fake.country[]}\n"
]
if __name__ == "__main__":
parser = argparse.ArgumentParser[description="Generate some fake data"]
parser.add_argument[
"--file-name",
type=str,
default="fake_user.csv",
help="file name to store fake data",
]
parser.add_argument[
"--num-records", type=int, default=100, help="Num of records to generate"
]
parser.add_argument["--seed", type=int, default=0, help="seed"]
args = parser.parse_args[]
gen_user_data[
file_name=args.file_name, num_records=args.num_records, seed=args.seed
]
7 mỗi hàng. Cấp quyền cho trình tạo dữ liệu giả và tạo 10 triệu hàng như hình bên dướichmod u+rwx gen_fake.py
# run 5 parallel processes, each generating 2million records as shown below
./gen_fake.py --file-name user_data_1.csv --num-records 2000000 --seed 0 & ./gen_fake.py --file-name user_data_2.csv --num-records 2000000 --seed 2000000 & ./gen_fake.py --file-name user_data_3.csv --num-records 2000000 --seed 4000000 & ./gen_fake.py --file-name user_data_4.csv --num-records 2000000 --seed 6000000 & ./gen_fake.py --file-name user_data_5.csv --num-records 2000000 --seed 8000000
mkdir data
cat user_data_1.csv user_data_2.csv user_data_3.csv user_data_4.csv user_data_5.csv >> ./data/user_data_fin.csv # combine data
rm user_data_1* user_data_2* user_data_3* user_data_4* user_data_5*
Hãy bắt đầu một bộ chứa MySQL với dữ liệu chúng tôi đã tạo ở trên và đăng nhập vào đó
________số 8
Tạo một cơ sở dữ liệu có tên là
#!/usr/bin/env python3
import argparse
import random
from faker import Faker
def gen_user_data[file_name: str, num_records: int, seed: int = 1] -> None:
fake = Faker["en_US"]
with open[file_name, "w"] as file1:
for i in range[1, num_records + 1]:
file1.write[
f"{seed + i},{fake.name[]},{random.randint[0,1]},{fake.state[]},{fake.country[]}\n"
]
if __name__ == "__main__":
parser = argparse.ArgumentParser[description="Generate some fake data"]
parser.add_argument[
"--file-name",
type=str,
default="fake_user.csv",
help="file name to store fake data",
]
parser.add_argument[
"--num-records", type=int, default=100, help="Num of records to generate"
]
parser.add_argument["--seed", type=int, default=0, help="seed"]
args = parser.parse_args[]
gen_user_data[
file_name=args.file_name, num_records=args.num_records, seed=args.seed
]
8 và một bảng #!/usr/bin/env python3
import argparse
import random
from faker import Faker
def gen_user_data[file_name: str, num_records: int, seed: int = 1] -> None:
fake = Faker["en_US"]
with open[file_name, "w"] as file1:
for i in range[1, num_records + 1]:
file1.write[
f"{seed + i},{fake.name[]},{random.randint[0,1]},{fake.state[]},{fake.country[]}\n"
]
if __name__ == "__main__":
parser = argparse.ArgumentParser[description="Generate some fake data"]
parser.add_argument[
"--file-name",
type=str,
default="fake_user.csv",
help="file name to store fake data",
]
parser.add_argument[
"--num-records", type=int, default=100, help="Num of records to generate"
]
parser.add_argument["--seed", type=int, default=0, help="seed"]
args = parser.parse_args[]
gen_user_data[
file_name=args.file_name, num_records=args.num_records, seed=args.seed
]
9 đơn giản. Chèn dữ liệu được tạo vào bảng như hình bên dưới#!/usr/bin/env python3
import argparse
import random
from faker import Faker
def gen_user_data[file_name: str, num_records: int, seed: int = 1] -> None:
fake = Faker["en_US"]
with open[file_name, "w"] as file1:
for i in range[1, num_records + 1]:
file1.write[
f"{seed + i},{fake.name[]},{random.randint[0,1]},{fake.state[]},{fake.country[]}\n"
]
if __name__ == "__main__":
parser = argparse.ArgumentParser[description="Generate some fake data"]
parser.add_argument[
"--file-name",
type=str,
default="fake_user.csv",
help="file name to store fake data",
]
parser.add_argument[
"--num-records", type=int, default=100, help="Num of records to generate"
]
parser.add_argument["--seed", type=int, default=0, help="seed"]
args = parser.parse_args[]
gen_user_data[
file_name=args.file_name, num_records=args.num_records, seed=args.seed
]
1Sự cố với một bản cập nhật lớnGiả sử chúng ta làm việc cho một trang web thương mại điện tử. Một lỗi đã được đưa vào sản xuất và hiện chúng tôi có trường
chmod u+rwx gen_fake.py
# run 5 parallel processes, each generating 2million records as shown below
./gen_fake.py --file-name user_data_1.csv --num-records 2000000 --seed 0 & ./gen_fake.py --file-name user_data_2.csv --num-records 2000000 --seed 2000000 & ./gen_fake.py --file-name user_data_3.csv --num-records 2000000 --seed 4000000 & ./gen_fake.py --file-name user_data_4.csv --num-records 2000000 --seed 6000000 & ./gen_fake.py --file-name user_data_5.csv --num-records 2000000 --seed 8000000
mkdir data
cat user_data_1.csv user_data_2.csv user_data_3.csv user_data_4.csv user_data_5.csv >> ./data/user_data_fin.csv # combine data
rm user_data_1* user_data_2* user_data_3* user_data_4* user_data_5*
0[trạng thái] được đặt không chính xác cho người dùng có id từ 3 triệu[3000000] đến 8 triệu[8000000]Chúng tôi phải cập nhật 5 triệu bản ghi trong tổng số 10 triệu bản ghi để đặt giá trị
chmod u+rwx gen_fake.py
# run 5 parallel processes, each generating 2million records as shown below
./gen_fake.py --file-name user_data_1.csv --num-records 2000000 --seed 0 & ./gen_fake.py --file-name user_data_2.csv --num-records 2000000 --seed 2000000 & ./gen_fake.py --file-name user_data_3.csv --num-records 2000000 --seed 4000000 & ./gen_fake.py --file-name user_data_4.csv --num-records 2000000 --seed 6000000 & ./gen_fake.py --file-name user_data_5.csv --num-records 2000000 --seed 8000000
mkdir data
cat user_data_1.csv user_data_2.csv user_data_3.csv user_data_4.csv user_data_5.csv >> ./data/user_data_fin.csv # combine data
rm user_data_1* user_data_2* user_data_3* user_data_4* user_data_5*
0 thành chmod u+rwx gen_fake.py
# run 5 parallel processes, each generating 2million records as shown below
./gen_fake.py --file-name user_data_1.csv --num-records 2000000 --seed 0 & ./gen_fake.py --file-name user_data_2.csv --num-records 2000000 --seed 2000000 & ./gen_fake.py --file-name user_data_3.csv --num-records 2000000 --seed 4000000 & ./gen_fake.py --file-name user_data_4.csv --num-records 2000000 --seed 6000000 & ./gen_fake.py --file-name user_data_5.csv --num-records 2000000 --seed 8000000
mkdir data
cat user_data_1.csv user_data_2.csv user_data_3.csv user_data_4.csv user_data_5.csv >> ./data/user_data_fin.csv # combine data
rm user_data_1* user_data_2* user_data_3* user_data_4* user_data_5*
2. Một hạn chế mà chúng tôi đang làm việc là giữ cho thời gian ngừng hoạt động của người dùng càng nhỏ càng tốt. Nếu bạn là người dùng và hồ sơ của bạn bị khóa, bạn sẽ không thể sửa đổi dữ liệu của mình. Hãy xem trải nghiệm người dùng có thể bị ảnh hưởng như thế nào bởi một bản cập nhật lớn đang khóa hồ sơ của họTrong thiết bị đầu cuối sql của bạn chạy lệnh cập nhật này
#!/usr/bin/env python3
import argparse
import random
from faker import Faker
def gen_user_data[file_name: str, num_records: int, seed: int = 1] -> None:
fake = Faker["en_US"]
with open[file_name, "w"] as file1:
for i in range[1, num_records + 1]:
file1.write[
f"{seed + i},{fake.name[]},{random.randint[0,1]},{fake.state[]},{fake.country[]}\n"
]
if __name__ == "__main__":
parser = argparse.ArgumentParser[description="Generate some fake data"]
parser.add_argument[
"--file-name",
type=str,
default="fake_user.csv",
help="file name to store fake data",
]
parser.add_argument[
"--num-records", type=int, default=100, help="Num of records to generate"
]
parser.add_argument["--seed", type=int, default=0, help="seed"]
args = parser.parse_args[]
gen_user_data[
file_name=args.file_name, num_records=args.num_records, seed=args.seed
]
5Đồng thời, trong một thiết bị đầu cuối sql khác, hãy thử cập nhật bản ghi người dùng bị khóa bởi bản cập nhật ở trên. Chúng tôi sử dụng where
chmod u+rwx gen_fake.py
# run 5 parallel processes, each generating 2million records as shown below
./gen_fake.py --file-name user_data_1.csv --num-records 2000000 --seed 0 & ./gen_fake.py --file-name user_data_2.csv --num-records 2000000 --seed 2000000 & ./gen_fake.py --file-name user_data_3.csv --num-records 2000000 --seed 4000000 & ./gen_fake.py --file-name user_data_4.csv --num-records 2000000 --seed 6000000 & ./gen_fake.py --file-name user_data_5.csv --num-records 2000000 --seed 8000000
mkdir data
cat user_data_1.csv user_data_2.csv user_data_3.csv user_data_4.csv user_data_5.csv >> ./data/user_data_fin.csv # combine data
rm user_data_1* user_data_2* user_data_3* user_data_4* user_data_5*
3 để chọn một hàng bị khóa bởi bản cập nhật ở trên#!/usr/bin/env python3
import argparse
import random
from faker import Faker
def gen_user_data[file_name: str, num_records: int, seed: int = 1] -> None:
fake = Faker["en_US"]
with open[file_name, "w"] as file1:
for i in range[1, num_records + 1]:
file1.write[
f"{seed + i},{fake.name[]},{random.randint[0,1]},{fake.state[]},{fake.country[]}\n"
]
if __name__ == "__main__":
parser = argparse.ArgumentParser[description="Generate some fake data"]
parser.add_argument[
"--file-name",
type=str,
default="fake_user.csv",
help="file name to store fake data",
]
parser.add_argument[
"--num-records", type=int, default=100, help="Num of records to generate"
]
parser.add_argument["--seed", type=int, default=0, help="seed"]
args = parser.parse_args[]
gen_user_data[
file_name=args.file_name, num_records=args.num_records, seed=args.seed
]
7#!/usr/bin/env python3
import argparse
import random
from faker import Faker
def gen_user_data[file_name: str, num_records: int, seed: int = 1] -> None:
fake = Faker["en_US"]
with open[file_name, "w"] as file1:
for i in range[1, num_records + 1]:
file1.write[
f"{seed + i},{fake.name[]},{random.randint[0,1]},{fake.state[]},{fake.country[]}\n"
]
if __name__ == "__main__":
parser = argparse.ArgumentParser[description="Generate some fake data"]
parser.add_argument[
"--file-name",
type=str,
default="fake_user.csv",
help="file name to store fake data",
]
parser.add_argument[
"--num-records", type=int, default=100, help="Num of records to generate"
]
parser.add_argument["--seed", type=int, default=0, help="seed"]
args = parser.parse_args[]
gen_user_data[
file_name=args.file_name, num_records=args.num_records, seed=args.seed
]
8Lỗi này xảy ra do bản cập nhật lớn của chúng tôi đã khóa bản ghi với
chmod u+rwx gen_fake.py
# run 5 parallel processes, each generating 2million records as shown below
./gen_fake.py --file-name user_data_1.csv --num-records 2000000 --seed 0 & ./gen_fake.py --file-name user_data_2.csv --num-records 2000000 --seed 2000000 & ./gen_fake.py --file-name user_data_3.csv --num-records 2000000 --seed 4000000 & ./gen_fake.py --file-name user_data_4.csv --num-records 2000000 --seed 6000000 & ./gen_fake.py --file-name user_data_5.csv --num-records 2000000 --seed 8000000
mkdir data
cat user_data_1.csv user_data_2.csv user_data_3.csv user_data_4.csv user_data_5.csv >> ./data/user_data_fin.csv # combine data
rm user_data_1* user_data_2* user_data_3* user_data_4* user_data_5*
3 và điều này ngăn bất kỳ giao dịch nào khác sửa đổi dữ liệu bị khóaBản cập nhật thứ hai sẽ đợi theo mặc định 50 giây [được đặt là
chmod u+rwx gen_fake.py
# run 5 parallel processes, each generating 2million records as shown below
./gen_fake.py --file-name user_data_1.csv --num-records 2000000 --seed 0 & ./gen_fake.py --file-name user_data_2.csv --num-records 2000000 --seed 2000000 & ./gen_fake.py --file-name user_data_3.csv --num-records 2000000 --seed 4000000 & ./gen_fake.py --file-name user_data_4.csv --num-records 2000000 --seed 6000000 & ./gen_fake.py --file-name user_data_5.csv --num-records 2000000 --seed 8000000
mkdir data
cat user_data_1.csv user_data_2.csv user_data_3.csv user_data_4.csv user_data_5.csv >> ./data/user_data_fin.csv # combine data
rm user_data_1* user_data_2* user_data_3* user_data_4* user_data_5*
5] trước khi hết thời gian chờ. Bạn có thể kiểm tra cài đặt này bằng truy vấn bên dướimkdir lock_update && cd lock_update
1Điều gì sẽ xảy ra nếu thay vì cập nhật 5 triệu bản ghi trong một câu lệnh cập nhật, chúng tôi chỉ cập nhật một số bản ghi người dùng tại một thời điểm?
Cập nhật hàng loạtHãy chạy các bản cập nhật theo lô 50.000 bản ghi. Hãy xem cách chúng tôi có thể cập nhật bảng người dùng của mình theo khối
Trong bảng người dùng của chúng tôi, chúng tôi có một cột chính là id tăng dần một cách đơn điệu. Chúng tôi có thể sử dụng điều này để phân chia các bản cập nhật của mình thành các lô 50.000 bản ghi người dùng. Giả sử lần này chúng ta muốn thiết lập kỷ lục
chmod u+rwx gen_fake.py
# run 5 parallel processes, each generating 2million records as shown below
./gen_fake.py --file-name user_data_1.csv --num-records 2000000 --seed 0 & ./gen_fake.py --file-name user_data_2.csv --num-records 2000000 --seed 2000000 & ./gen_fake.py --file-name user_data_3.csv --num-records 2000000 --seed 4000000 & ./gen_fake.py --file-name user_data_4.csv --num-records 2000000 --seed 6000000 & ./gen_fake.py --file-name user_data_5.csv --num-records 2000000 --seed 8000000
mkdir data
cat user_data_1.csv user_data_2.csv user_data_3.csv user_data_4.csv user_data_5.csv >> ./data/user_data_fin.csv # combine data
rm user_data_1* user_data_2* user_data_3* user_data_4* user_data_5*
0 thành chmod u+rwx gen_fake.py
# run 5 parallel processes, each generating 2million records as shown below
./gen_fake.py --file-name user_data_1.csv --num-records 2000000 --seed 0 & ./gen_fake.py --file-name user_data_2.csv --num-records 2000000 --seed 2000000 & ./gen_fake.py --file-name user_data_3.csv --num-records 2000000 --seed 4000000 & ./gen_fake.py --file-name user_data_4.csv --num-records 2000000 --seed 6000000 & ./gen_fake.py --file-name user_data_5.csv --num-records 2000000 --seed 8000000
mkdir data
cat user_data_1.csv user_data_2.csv user_data_3.csv user_data_4.csv user_data_5.csv >> ./data/user_data_fin.csv # combine data
rm user_data_1* user_data_2* user_data_3* user_data_4* user_data_5*
7Để chạy các bản cập nhật trong
chmod u+rwx gen_fake.py
# run 5 parallel processes, each generating 2million records as shown below
./gen_fake.py --file-name user_data_1.csv --num-records 2000000 --seed 0 & ./gen_fake.py --file-name user_data_2.csv --num-records 2000000 --seed 2000000 & ./gen_fake.py --file-name user_data_3.csv --num-records 2000000 --seed 4000000 & ./gen_fake.py --file-name user_data_4.csv --num-records 2000000 --seed 6000000 & ./gen_fake.py --file-name user_data_5.csv --num-records 2000000 --seed 8000000
mkdir data
cat user_data_1.csv user_data_2.csv user_data_3.csv user_data_4.csv user_data_5.csv >> ./data/user_data_fin.csv # combine data
rm user_data_1* user_data_2* user_data_3* user_data_4* user_data_5*
8, chúng ta cần tạo một thủ tục được lưu trữ để đóng gói logic này. Logic vòng lặp rất đơn giản. Chúng tôi tạo một cửa sổ trượt được xác định bằng id bắt đầu của chmod u+rwx gen_fake.py
# run 5 parallel processes, each generating 2million records as shown below
./gen_fake.py --file-name user_data_1.csv --num-records 2000000 --seed 0 & ./gen_fake.py --file-name user_data_2.csv --num-records 2000000 --seed 2000000 & ./gen_fake.py --file-name user_data_3.csv --num-records 2000000 --seed 4000000 & ./gen_fake.py --file-name user_data_4.csv --num-records 2000000 --seed 6000000 & ./gen_fake.py --file-name user_data_5.csv --num-records 2000000 --seed 8000000
mkdir data
cat user_data_1.csv user_data_2.csv user_data_3.csv user_data_4.csv user_data_5.csv >> ./data/user_data_fin.csv # combine data
rm user_data_1* user_data_2* user_data_3* user_data_4* user_data_5*
9 và id kết thúc của docker run -d -p 3306:3306 --name mysql-updates -v "$[pwd]"/data:/var/lib/data -e MYSQL_ROOT_PASSWORD=Password1234 mysql:8.0
docker exec -it mysql-updates bash # open docker shell
mysql -h 127.0.0.1 -P 3306 -u root --local-infile=1 -p # password is Password1234
0, được tăng lên bởi docker run -d -p 3306:3306 --name mysql-updates -v "$[pwd]"/data:/var/lib/data -e MYSQL_ROOT_PASSWORD=Password1234 mysql:8.0
docker exec -it mysql-updates bash # open docker shell
mysql -h 127.0.0.1 -P 3306 -u root --local-infile=1 -p # password is Password1234
1 cho mỗi lần chạyLưu ý rằng chúng tôi sử dụng
docker run -d -p 3306:3306 --name mysql-updates -v "$[pwd]"/data:/var/lib/data -e MYSQL_ROOT_PASSWORD=Password1234 mysql:8.0
docker exec -it mysql-updates bash # open docker shell
mysql -h 127.0.0.1 -P 3306 -u root --local-infile=1 -p # password is Password1234
2 để đặt dấu phân cách câu lệnh thành docker run -d -p 3306:3306 --name mysql-updates -v "$[pwd]"/data:/var/lib/data -e MYSQL_ROOT_PASSWORD=Password1234 mysql:8.0
docker exec -it mysql-updates bash # open docker shell
mysql -h 127.0.0.1 -P 3306 -u root --local-infile=1 -p # password is Password1234
3. Điều này cho phép chúng tôi sử dụng dấu phân cách mặc định của MySQL là docker run -d -p 3306:3306 --name mysql-updates -v "$[pwd]"/data:/var/lib/data -e MYSQL_ROOT_PASSWORD=Password1234 mysql:8.0
docker exec -it mysql-updates bash # open docker shell
mysql -h 127.0.0.1 -P 3306 -u root --local-infile=1 -p # password is Password1234
4 trong định nghĩa thủ tục được lưu trữ. Bạn có thể thấy rằng sau lệnh docker run -d -p 3306:3306 --name mysql-updates -v "$[pwd]"/data:/var/lib/data -e MYSQL_ROOT_PASSWORD=Password1234 mysql:8.0
docker exec -it mysql-updates bash # open docker shell
mysql -h 127.0.0.1 -P 3306 -u root --local-infile=1 -p # password is Password1234
5, chúng tôi đặt dấu phân cách trở lại docker run -d -p 3306:3306 --name mysql-updates -v "$[pwd]"/data:/var/lib/data -e MYSQL_ROOT_PASSWORD=Password1234 mysql:8.0
docker exec -it mysql-updates bash # open docker shell
mysql -h 127.0.0.1 -P 3306 -u root --local-infile=1 -p # password is Password1234
4#!/usr/bin/env python3
import argparse
import random
from faker import Faker
def gen_user_data[file_name: str, num_records: int, seed: int = 1] -> None:
fake = Faker["en_US"]
with open[file_name, "w"] as file1:
for i in range[1, num_records + 1]:
file1.write[
f"{seed + i},{fake.name[]},{random.randint[0,1]},{fake.state[]},{fake.country[]}\n"
]
if __name__ == "__main__":
parser = argparse.ArgumentParser[description="Generate some fake data"]
parser.add_argument[
"--file-name",
type=str,
default="fake_user.csv",
help="file name to store fake data",
]
parser.add_argument[
"--num-records", type=int, default=100, help="Num of records to generate"
]
parser.add_argument["--seed", type=int, default=0, help="seed"]
args = parser.parse_args[]
gen_user_data[
file_name=args.file_name, num_records=args.num_records, seed=args.seed
]
3Câu lệnh cập nhật cuối cùng bên ngoài vòng lặp while được sử dụng để cập nhật các bản ghi bị bỏ sót trong vòng lặp. Chúng tôi cũng có một số báo cáo nhật ký để in ra các khối hiện đang được cập nhật. Vì MySQL
docker run -d -p 3306:3306 --name mysql-updates -v "$[pwd]"/data:/var/lib/data -e MYSQL_ROOT_PASSWORD=Password1234 mysql:8.0
docker exec -it mysql-updates bash # open docker shell
mysql -h 127.0.0.1 -P 3306 -u root --local-infile=1 -p # password is Password1234
7 đã bao gồm nên chúng tôi đang cập nhật lại docker run -d -p 3306:3306 --name mysql-updates -v "$[pwd]"/data:/var/lib/data -e MYSQL_ROOT_PASSWORD=Password1234 mysql:8.0
docker exec -it mysql-updates bash # open docker shell
mysql -h 127.0.0.1 -P 3306 -u root --local-infile=1 -p # password is Password1234
0 của đoạn trước. Hãy chú ý đến điều này cho logic của bạnTrong khi
docker run -d -p 3306:3306 --name mysql-updates -v "$[pwd]"/data:/var/lib/data -e MYSQL_ROOT_PASSWORD=Password1234 mysql:8.0
docker exec -it mysql-updates bash # open docker shell
mysql -h 127.0.0.1 -P 3306 -u root --local-infile=1 -p # password is Password1234
9 ở trên đang chạy, hãy chạy một bản cập nhật trong ứng dụng khách sql khác#!/usr/bin/env python3
import argparse
import random
from faker import Faker
def gen_user_data[file_name: str, num_records: int, seed: int = 1] -> None:
fake = Faker["en_US"]
with open[file_name, "w"] as file1:
for i in range[1, num_records + 1]:
file1.write[
f"{seed + i},{fake.name[]},{random.randint[0,1]},{fake.state[]},{fake.country[]}\n"
]
if __name__ == "__main__":
parser = argparse.ArgumentParser[description="Generate some fake data"]
parser.add_argument[
"--file-name",
type=str,
default="fake_user.csv",
help="file name to store fake data",
]
parser.add_argument[
"--num-records", type=int, default=100, help="Num of records to generate"
]
parser.add_argument["--seed", type=int, default=0, help="seed"]
args = parser.parse_args[]
gen_user_data[
file_name=args.file_name, num_records=args.num_records, seed=args.seed
]
7#!/usr/bin/env python3
import argparse
import random
from faker import Faker
def gen_user_data[file_name: str, num_records: int, seed: int = 1] -> None:
fake = Faker["en_US"]
with open[file_name, "w"] as file1:
for i in range[1, num_records + 1]:
file1.write[
f"{seed + i},{fake.name[]},{random.randint[0,1]},{fake.state[]},{fake.country[]}\n"
]
if __name__ == "__main__":
parser = argparse.ArgumentParser[description="Generate some fake data"]
parser.add_argument[
"--file-name",
type=str,
default="fake_user.csv",
help="file name to store fake data",
]
parser.add_argument[
"--num-records", type=int, default=100, help="Num of records to generate"
]
parser.add_argument["--seed", type=int, default=0, help="seed"]
args = parser.parse_args[]
gen_user_data[
file_name=args.file_name, num_records=args.num_records, seed=args.seed
]
1Bản cập nhật này thực hiện nhanh chóng. Mặc dù bản cập nhật lớn mất nhiều thời gian hơn do chúng tôi thực hiện theo đợt, nhưng chúng tôi có thể thấy cách tiếp cận này cho phép các giao dịch khác chỉnh sửa dữ liệu
Phần kết luậnBạn có thể phá bỏ các thùng chứa docker của mình bằng các lệnh sau
#!/usr/bin/env python3
import argparse
import random
from faker import Faker
def gen_user_data[file_name: str, num_records: int, seed: int = 1] -> None:
fake = Faker["en_US"]
with open[file_name, "w"] as file1:
for i in range[1, num_records + 1]:
file1.write[
f"{seed + i},{fake.name[]},{random.randint[0,1]},{fake.state[]},{fake.country[]}\n"
]
if __name__ == "__main__":
parser = argparse.ArgumentParser[description="Generate some fake data"]
parser.add_argument[
"--file-name",
type=str,
default="fake_user.csv",
help="file name to store fake data",
]
parser.add_argument[
"--num-records", type=int, default=100, help="Num of records to generate"
]
parser.add_argument["--seed", type=int, default=0, help="seed"]
args = parser.parse_args[]
gen_user_data[
file_name=args.file_name, num_records=args.num_records, seed=args.seed
]
2Tóm lại, chúng tôi đã thấy
- làm thế nào một bản cập nhật lớn có thể khóa các hoạt động cập nhật và xóa khác và gây ra lỗi
10#!/usr/bin/env python3 import argparse import random from faker import Faker def gen_user_data[file_name: str, num_records: int, seed: int = 1] -> None: fake = Faker["en_US"] with open[file_name, "w"] as file1: for i in range[1, num_records + 1]: file1.write[ f"{seed + i},{fake.name[]},{random.randint[0,1]},{fake.state[]},{fake.country[]}\n" ] if __name__ == "__main__": parser = argparse.ArgumentParser[description="Generate some fake data"] parser.add_argument[ "--file-name", type=str, default="fake_user.csv", help="file name to store fake data", ] parser.add_argument[ "--num-records", type=int, default=100, help="Num of records to generate" ] parser.add_argument["--seed", type=int, default=0, help="seed"] args = parser.parse_args[] gen_user_data[ file_name=args.file_name, num_records=args.num_records, seed=args.seed ]
- cách cập nhật theo lô nhỏ hơn thực hiện nhanh hơn trên mỗi đợt và do đó, khóa sẽ chỉ phải chờ vài giây, nếu có
Một điểm quan trọng cần lưu ý ở đây là thứ tự cập nhật. Khi chạy cập nhật hàng loạt và cập nhật đơn lẻ trên cùng một cột của bản ghi, bản cập nhật mới nhất sẽ được áp dụng. Bạn cũng có thể thực hiện cập nhật hàng loạt này song song, nhưng bạn phải cẩn thận để không gặp phải bất kỳ bế tắc nào
Nếu logic cập nhật phức tạp hơn và bảng của bạn có chỉ mục, bạn có thể sử dụng
#!/usr/bin/env python3
import argparse
import random
from faker import Faker
def gen_user_data[file_name: str, num_records: int, seed: int = 1] -> None:
fake = Faker["en_US"]
with open[file_name, "w"] as file1:
for i in range[1, num_records + 1]:
file1.write[
f"{seed + i},{fake.name[]},{random.randint[0,1]},{fake.state[]},{fake.country[]}\n"
]
if __name__ == "__main__":
parser = argparse.ArgumentParser[description="Generate some fake data"]
parser.add_argument[
"--file-name",
type=str,
default="fake_user.csv",
help="file name to store fake data",
]
parser.add_argument[
"--num-records", type=int, default=100, help="Num of records to generate"
]
parser.add_argument["--seed", type=int, default=0, help="seed"]
args = parser.parse_args[]
gen_user_data[
file_name=args.file_name, num_records=args.num_records, seed=args.seed
]
11 với các tính năng của #!/usr/bin/env python3
import argparse
import random
from faker import Faker
def gen_user_data[file_name: str, num_records: int, seed: int = 1] -> None:
fake = Faker["en_US"]
with open[file_name, "w"] as file1:
for i in range[1, num_records + 1]:
file1.write[
f"{seed + i},{fake.name[]},{random.randint[0,1]},{fake.state[]},{fake.country[]}\n"
]
if __name__ == "__main__":
parser = argparse.ArgumentParser[description="Generate some fake data"]
parser.add_argument[
"--file-name",
type=str,
default="fake_user.csv",
help="file name to store fake data",
]
parser.add_argument[
"--num-records", type=int, default=100, help="Num of records to generate"
]
parser.add_argument["--seed", type=int, default=0, help="seed"]
args = parser.parse_args[]
gen_user_data[
file_name=args.file_name, num_records=args.num_records, seed=args.seed
]
12 hoặc #!/usr/bin/env python3
import argparse
import random
from faker import Faker
def gen_user_data[file_name: str, num_records: int, seed: int = 1] -> None:
fake = Faker["en_US"]
with open[file_name, "w"] as file1:
for i in range[1, num_records + 1]:
file1.write[
f"{seed + i},{fake.name[]},{random.randint[0,1]},{fake.state[]},{fake.country[]}\n"
]
if __name__ == "__main__":
parser = argparse.ArgumentParser[description="Generate some fake data"]
parser.add_argument[
"--file-name",
type=str,
default="fake_user.csv",
help="file name to store fake data",
]
parser.add_argument[
"--num-records", type=int, default=100, help="Num of records to generate"
]
parser.add_argument["--seed", type=int, default=0, help="seed"]
args = parser.parse_args[]
gen_user_data[
file_name=args.file_name, num_records=args.num_records, seed=args.seed
]
13 như được hiển thị tại đâyLần tới khi bạn thực hiện một bản cập nhật lớn trên bảng, hãy cân nhắc chạy các bản cập nhật theo khối để giữ cho các giao dịch khác không bị ảnh hưởng bởi lỗi hết thời gian khóa