Compare commits

...

15 Commits

Author SHA1 Message Date
Dylan Richardson
1ae4c9990d Update authenticode key name (#45424)
This commit adjusts our authenticode key name from an expired one to our current signing key
2025-12-22 15:06:05 -08:00
Didier Nadeau
2efece39cc SERVER-115508 Make minimally sized buffers for uncompressed Messages 2025-12-22 15:06:05 -08:00
Dylan Richardson
cb802868a9 Revert "SERVER-86363: Make container registry login silent (#18796)"
This reverts commit b1c5279044e35a16389c1157cf63f332f19006ea.
2025-12-22 15:06:05 -08:00
Dylan Richardson
ec2eddc00c Revert "SERVER-87567 The SessionWorkflow should correctly return a response error on malformed requests"
This reverts commit 695dee0c78e78d029e1d2eeb2c82b6b938c5e324.
2025-12-22 15:06:05 -08:00
Dylan Richardson
ccf485934c Revert "SERVER-88212 No op commit 1 of 3 to populate perf data (#20129)"
This reverts commit 3609b7fcfc39b8b449a9b601d85a3d7562d3a33d.
2025-12-22 15:06:05 -08:00
Dylan Richardson
7b19184fcd Revert "SERVER-85368: Update genny module organization to mongodb. (#20089)"
This reverts commit e05155572030b3aa6a8f3cc794ec5be8bc17acee.
2025-12-22 15:06:05 -08:00
Dylan Richardson
6a63b7fe22 Revert "SERVER-88212 No op commit 2 of 3 to populate perf data (#20130)"
This reverts commit e9cb02b38dee4eaa033ebce00e7b9154e3ffc5ab.
2025-12-22 15:06:05 -08:00
Dylan Richardson
e24a0feb72 Revert "SERVER-88212 No op commit 3 of 3 to populate perf data (#20132)"
This reverts commit ae1112d05445ad6e690f440b1eee962747267124.
2025-12-22 15:06:05 -08:00
Dylan Richardson
a8b03f81fa Revert "SERVER-79999 reduce macOS test coverage (#18350)"
This reverts commit 410adbfe7484ef18bd90213b2828661b273906e5.
2025-12-22 15:06:05 -08:00
Dylan Richardson
722bdbc7cc Revert "SERVER-77559, SERVER-77560: Implement Evergreen file system log handler for resmoke and update resmoke test results (#21826)"
This reverts commit 7f15b1145e41081994fe250dba9e1e0347794aae.
2025-12-22 15:06:05 -08:00
Dylan Richardson
c326c9a2b2 Revert "SERVER-77561: configurable resmoke logger and buffered file handler for resmoke logging"
This reverts commit 9627f667c70d6ee3d4958c2a41f3502ecfce6548.
2025-12-22 15:06:05 -08:00
Dylan Richardson
ab382cff67 Revert "SERVER-90264 Delete references to distsrc in evergreen config (#21965)"
This reverts commit aa98242b1cfe6b1d557401aab6c937684e5c8e89.
2025-12-22 15:06:05 -08:00
Dylan Richardson
6d0568e1ec Revert "Import wiredtiger: 45abc546f55273dcbb226354b7e0e350e039e4e9 from branch mongodb-4.4"
This reverts commit 3ae3eddb3ba5cb7dd27c00db69097ee0747e2255.
2025-12-22 15:06:05 -08:00
Dylan Richardson
c9638fb418 Revert "Import wiredtiger: ec263e21b9912502a1f134f901e47aa155bdcc38 from branch mongodb-4.4"
This reverts commit 8b55f100b4e952428403aad44879852de71dd754.
2025-12-22 15:06:05 -08:00
Dylan Richardson
8b0b9b1d69 Revert "Import wiredtiger: 002ce30f6845d6d070252a5b014168f7265a9448 from branch mongodb-4.4"
This reverts commit af23f9edcd07d80f8483cac1291c3196dc2fa1a3.
2025-12-22 15:06:05 -08:00
34 changed files with 749 additions and 1131 deletions

View File

@@ -1,27 +0,0 @@
logging:
executor:
format: '[%(name)s] %(asctime)s %(message)s'
handlers:
- class: logging.StreamHandler
fixture:
format: '[%(name)s] %(message)s'
handlers:
- class: evergreen
tests:
format: '[%(name)s] %(message)s'
handlers:
- class: evergreen
shorten_logger_name:
remove:
- MongoDFixture
- ReplicaSetFixture
- ShardedClusterFixture
replace:
primary: prim
secondary: sec
node: n
shard: s
configsvr: c
mongos: s
job: j

View File

@@ -111,7 +111,6 @@ DEFAULTS = {
"task_name": None,
"variant_name": None,
"version_id": None,
"work_dir": None,
# WiredTiger options.
"wt_coll_config": None,
@@ -287,9 +286,6 @@ EVERGREEN_VARIANT_NAME = None
# the commit hash.
EVERGREEN_VERSION_ID = None
# The Evergreen task's working directory.
EVERGREEN_WORK_DIR = None
# If set, then any jstests that have any of the specified tags will be excluded from the suite(s).
EXCLUDE_WITH_ANY_TAGS = None

View File

@@ -240,7 +240,6 @@ or explicitly pass --installDir to the run subcommand of buildscripts/resmoke.py
_config.EVERGREEN_TASK_NAME = config.pop("task_name")
_config.EVERGREEN_VARIANT_NAME = config.pop("variant_name")
_config.EVERGREEN_VERSION_ID = config.pop("version_id")
_config.EVERGREEN_WORK_DIR = config.pop("work_dir")
# Archival options. Archival is enabled only when running on evergreen.
if not _config.EVERGREEN_TASK_ID:

View File

@@ -41,17 +41,3 @@ class ISO8601Formatter(logging.Formatter):
utc_offset_mins = (utc_offset_secs / 60) % 60
utc_offset_hours = utc_offset_secs / 3600
return "%s%02d%02d" % (utc_offset_prefix, utc_offset_hours, utc_offset_mins)
class EvergreenLogFormatter(logging.Formatter):
"""Log line formatter for Evergreen log messages.
See `https://docs.devprod.prod.corp.mongodb.com/evergreen/Project-Configuration/Task-Output-Directory#test-logs`
for more info.
"""
def format(self, record):
"""Return the Evergreen formatted record."""
ts = int(record.created * 1e9)
return "\n".join([f"{ts} {line}" for line in super().format(record).split("\n")])

View File

@@ -162,29 +162,6 @@ class BufferedHandler(logging.Handler):
logging.Handler.close(self)
class BufferedFileHandler(BufferedHandler):
"""File handler with in-memory buffering."""
def __init__(self, filename, capacity=2000, interval_secs=600):
"""Initialize the handler with the filename and buffer capacity and flush interval."""
super().__init__(capacity, interval_secs)
self.file = open(filename, "a")
def process_record(self, record):
"""Return the formatted record message appended with a newline."""
return self.format(record) + "\n"
def _flush_buffer_with_lock(self, buf, close_called):
"""Write the buffered log lines to the destination file."""
self.file.writelines(buf)
def close(self):
"""Close the handler and the file descriptor."""
super().close()
self.file.close()
class HTTPHandler(object):
"""A class which sends data to a web server using POST requests."""

View File

@@ -1,14 +1,10 @@
"""Module to hold the logger instances themselves."""
import logging
import os
import sys
import yaml
from . import buildlogger
from . import formatters
from . import handlers
from .. import config
from .. import errors
_DEFAULT_FORMAT = "[%(name)s] %(message)s"
@@ -48,13 +44,6 @@ def configure_loggers(logging_config):
EXECUTOR_LOGGER = ExecutorRootLogger(logging_config, build_logger_server, fixture_logger,
tests_logger)
_write_evergreen_log_spec()
def get_evergreen_log_name(job_num, test_id=None):
"""Return the log name, relative to the reserved test log directory, on the Evergreen task host."""
return f"job{job_num}/" + (f"{test_id}.log" if test_id else "global.log")
class BaseLogger(logging.Logger):
"""Base class for the custom loggers used in this library.
@@ -138,8 +127,6 @@ class RootLogger(BaseLogger):
handler = logging.StreamHandler(sys.stdout)
elif handler_class == "buildlogger":
return # Buildlogger handlers are applied when creating specific child loggers
elif handler_class == "evergreen":
return # Evergreen handlers are applied when creating specific child loggers
else:
raise ValueError("Unknown handler class '%s'" % handler_class)
handler.setFormatter(formatter)
@@ -205,46 +192,42 @@ class JobLogger(BaseLogger):
"""Create a new fixture logger that will be a child of the "fixture" root logger."""
return FixtureLogger(fixture_class, self.job_num, self.build_id, self.fixture_root_logger)
def new_test_logger(self, test_id, test_shortname, test_basename, command, parent): # pylint: disable=too-many-arguments
def new_test_logger(self, test_shortname, test_basename, command, parent):
"""Create a new test logger that will be a child of the given parent."""
if self.build_id:
# If we're configured to log messages to the buildlogger server, then request a new
# test id for this test.
build_test_id = self.build_logger_server.new_test_id(self.build_id, test_basename,
command)
if not build_test_id:
# test_id for this test.
test_id = self.build_logger_server.new_test_id(self.build_id, test_basename, command)
if not test_id:
buildlogger.set_log_output_incomplete()
raise errors.LoggerRuntimeConfigError(
"Encountered an error configuring buildlogger for test {}: Failed to get a new"
" test_id".format(test_basename))
url = self.build_logger_server.get_test_log_url(self.build_id, build_test_id)
url = self.build_logger_server.get_test_log_url(self.build_id, test_id)
self.info("Writing output of %s to %s.", test_basename, url)
return TestLogger(test_shortname, parent, self.job_num, self.build_id, build_test_id,
url)
return TestLogger(test_shortname, parent, self.build_id, test_id, url)
return TestLogger(test_shortname, parent, job_num=self.job_num, test_id=test_id)
return TestLogger(test_shortname, parent)
class TestLogger(BaseLogger):
"""TestLogger class."""
def __init__( # pylint: disable=too-many-arguments
self, test_name, parent, job_num=None, build_id=None, test_id=None, url=None):
self, test_name, parent, build_id=None, test_id=None, url=None):
"""Initialize a TestLogger.
:param test_name: the test name.
:param parent: the parent logger.
:param job_num: the number of the job the test is running on.
:param build_id: the build logger build id.
:param test_id: the test id for the logger handler.
:param test_id: the build logger test id.
:param url: the build logger URL endpoint for the test.
"""
name = "%s:%s" % (parent.name, test_name)
BaseLogger.__init__(self, name, parent=parent)
self.url_endpoint = url
self._add_build_logger_handler(build_id, test_id)
_add_evergreen_handler(self, self.logging_config, job_num, test_id)
def _add_build_logger_handler(self, build_id, test_id):
logger_info = self.logging_config[TESTS_LOGGER_NAME]
@@ -286,7 +269,6 @@ class FixtureLogger(BaseLogger):
self.fixture_class = fixture_class
self.job_num = job_num
self._add_build_logger_handler(build_id)
_add_evergreen_handler(self, self.logging_config, job_num)
def _add_build_logger_handler(self, build_id):
logger_info = self.logging_config[FIXTURE_LOGGER_NAME]
@@ -388,55 +370,3 @@ def _get_buildlogger_handler_info(logger_info):
if handler_info.pop("class") == "buildlogger":
return handler_info
return None
# Utility functions for Evergreen file system logging.
# See `https://docs.devprod.prod.corp.mongodb.com/evergreen/Project-Configuration/Task-Output-Directory#test-logs`
# for more information.
def _write_evergreen_log_spec():
"""Configure file system logging for Evergreen tasks."""
if not config.EVERGREEN_WORK_DIR:
return
fp = f"{_get_evergreen_log_dirname()}/log_spec.yaml"
os.makedirs(os.path.dirname(fp), exist_ok=True)
EXECUTOR_LOGGER.info("Writing Evergreen test log spec to %s.", fp)
log_spec = {
"version": 0,
"format": "text-timestamp",
}
with open(fp, "w") as fd:
yaml.dump(log_spec, fd)
def _add_evergreen_handler(logger, logging_config, job_num, test_id=None):
"""Add a new evergreen handler to a logger."""
logger_info = logging_config[TESTS_LOGGER_NAME]
evergreen_handler_info = None
for handler_info in logger_info["handlers"]:
if handler_info["class"] == "evergreen":
evergreen_handler_info = handler_info
break
if evergreen_handler_info:
fp = f"{_get_evergreen_log_dirname()}/{get_evergreen_log_name(job_num, test_id)}"
os.makedirs(os.path.dirname(fp), exist_ok=True)
handler = handlers.BufferedFileHandler(fp)
handler.setFormatter(
formatters.EvergreenLogFormatter(fmt=logger_info.get("format", _DEFAULT_FORMAT)))
logger.addHandler(handler)
if test_id:
EXECUTOR_LOGGER.info("Writing output of %s to %s.", test_id, fp)
else:
EXECUTOR_LOGGER.info("Writing output of job #%d to %s.", job_num, fp)
def _get_evergreen_log_dirname():
"""Return the reserved directory for test logs on the Evergreen task host."""
return f"{config.EVERGREEN_WORK_DIR}/build/TestLogs"

View File

@@ -385,9 +385,6 @@ def _add_run(subparsers): # pylint: disable=too-many-statements
evergreen_options.add_argument("--versionId", dest="version_id", metavar="VERSION_ID",
help="Sets the version ID of the task.")
evergreen_options.add_argument("--taskWorkDir", dest="work_dir", metavar="TASK_WORK_DIR",
help="Sets the working directory of the task.")
benchmark_options = parser.add_argument_group(
title=_BENCHMARK_ARGUMENT_TITLE, description="Options for running Benchmark/Benchrun tests")

View File

@@ -4,7 +4,6 @@ This is used to support additional test status and timing information for the re
"""
import copy
import os
import threading
import time
import unittest
@@ -99,7 +98,6 @@ class TestReport(unittest.TestResult): # pylint: disable=too-many-instance-attr
unittest.TestResult.startTest(self, test)
test_info = _TestInfo(test.id(), test.test_name, test.dynamic)
test_info.group_id = f"job{self.job_logger.job_num}"
basename = test.basename()
command = test.as_command()
@@ -114,14 +112,10 @@ class TestReport(unittest.TestResult): # pylint: disable=too-many-instance-attr
self.num_dynamic += 1
# Set up the test-specific logger.
test_logger = self.job_logger.new_test_logger(test.id(), test.short_name(), test.basename(),
command, test.logger)
test_logger = self.job_logger.new_test_logger(test.short_name(), test.basename(), command,
test.logger)
test_info.url_endpoint = test_logger.url_endpoint
test_info.log_info = {
"log_name": logging.loggers.get_evergreen_log_name(self.job_logger.job_num, test.id()),
"logs_to_merge": [logging.loggers.get_evergreen_log_name(self.job_logger.job_num)],
"rendering_type": "resmoke", "version": 0
}
test.override_logger(test_logger)
test_info.start_time = time.time()
@@ -268,18 +262,13 @@ class TestReport(unittest.TestResult): # pylint: disable=too-many-instance-attr
for test_info in self.test_infos:
result = {
"test_file": test_info.test_file,
"group_id": test_info.group_id,
"status": test_info.evergreen_status,
"exit_code": test_info.return_code,
"start": test_info.start_time,
"end": test_info.end_time,
"elapsed": test_info.end_time - test_info.start_time,
"log_info": test_info.log_info,
}
if test_info.display_test_name is not None:
result["display_test_name"] = test_info.display_test_name
if test_info.url_endpoint is not None:
result["url"] = test_info.url_endpoint
result["url_raw"] = test_info.url_endpoint + "?raw=1"
@@ -306,9 +295,6 @@ class TestReport(unittest.TestResult): # pylint: disable=too-many-instance-attr
# Using test_file as the test id is ok here since the test id only needs to be unique
# during suite execution.
test_info = _TestInfo(test_file, test_file, is_dynamic)
test_info.display_test_name = result.get("display_test_name")
test_info.group_id = result.get("group_id")
test_info.log_info = result.get("log_info")
test_info.url_endpoint = result.get("url")
test_info.status = result["status"]
test_info.evergreen_status = test_info.status
@@ -362,8 +348,6 @@ class _TestInfo(object): # pylint: disable=too-many-instance-attributes
self.test_id = test_id
self.test_file = test_file
self.group_id = None
self.display_test_name = None
self.dynamic = dynamic
self.start_time = None
@@ -371,7 +355,6 @@ class _TestInfo(object): # pylint: disable=too-many-instance-attributes
self.status = None
self.evergreen_status = None
self.return_code = None
self.log_info = None
self.url_endpoint = None

View File

@@ -1387,11 +1387,11 @@ functions:
${san_options} \
${snmp_config_path} \
${resmoke_wrapper} \
$python buildscripts/resmoke.py run \
$python buildscripts/resmoke.py run \
${resmoke_args} \
$extra_args \
${test_flags} \
--log=${resmoke_logger} \
--log=buildlogger \
--staggerJobs=on \
--installDir=${install_dir|dist-test/bin} \
--buildId=${build_id} \
@@ -1404,7 +1404,6 @@ functions:
--taskName=${task_name} \
--variantName=${build_variant} \
--versionId=${version_id} \
--taskWorkDir='${workdir}' \
--archiveFile=archive.json \
--reportFile=report.json \
--perfReportFile=perf.json
@@ -7743,6 +7742,7 @@ tasks:
- func: "scons compile"
vars:
targets: >-
distsrc-${ext|tgz}
archive-dist
archive-dist-debug
archive-shell
@@ -7763,6 +7763,19 @@ tasks:
# Validate that this build_variant is listed as a known enterprise task for mongocryptd
PATH=$PATH:$HOME $python ../buildscripts/validate_mongocryptd.py --variant "${build_variant}" ../etc/evergreen.yml
fi
- command: s3.put
params:
aws_key: ${aws_key}
aws_secret: ${aws_secret}
local_file: src/distsrc.${ext|tgz}
remote_file: ${project}/${build_variant}/${revision}/sources/mongo-src-${build_id}.${ext|tgz}
bucket: mciuploads
permissions: public-read
content_type: ${content_type|application/gzip}
display_name: Source tarball
# We only need to upload the source tarball from one of the build variants
# because it should be the same everywhere, so just use rhel70/windows.
build_variants: [rhel70, windows]
- command: s3.put
params:
optional: true
@@ -7950,6 +7963,14 @@ tasks:
local_file: src/mh.tgz
build_variants: *mh_variants
# Fetch the sources (on relevant variants only)
- command: s3.get
params:
aws_key: ${aws_key}
aws_secret: ${aws_secret}
remote_file: ${project}/${build_variant}/${revision}/sources/mongo-src-${build_id}.${ext|tgz}
bucket: mciuploads
local_file: src/distsrc.${ext|tgz}
build_variants: [rhel70, windows]
- func: "apply compile expansions"
- func: "fetch dist debugsymbols"
- func: "set up remote credentials"
@@ -7961,7 +7982,6 @@ tasks:
- command: shell.exec
params:
shell: bash
silent: true
script: |
set -oe
echo "${release_tools_container_registry_password}" | podman login --password-stdin --username ${release_tools_container_registry_username} ${release_tools_container_registry}
@@ -8024,6 +8044,17 @@ tasks:
content_type: ${content_type|application/gzip}
remote_file: ${push_path}-STAGE/${push_name}/mh-${push_name}-${push_arch}-${suffix}-${task_id}.${ext|tgz}
build_variants: *mh_variants
# Put the source tarball
- command: s3.put
params:
aws_secret: ${aws_secret}
local_file: src/mongodb-src-${src_suffix}.${ext|tar.gz}
aws_key: ${aws_key}
bucket: build-push-testing
permissions: public-read
content_type: ${content_type|application/gzip}
remote_file: ${push_path}-STAGE/${push_name}/mongodb-src-${src_suffix}-${task_id}.${ext|tar.gz}
build_variants: [rhel70, windows]
# Put the debug symbols
- command: s3.put
@@ -8071,6 +8102,18 @@ tasks:
remote_file: ${push_path}-STAGE/${push_name}/mongodb-cryptd-${push_name}-${push_arch}-${suffix}-${task_id}.${ext|tgz}.sig
build_variants: *mongocryptd_variants
# Put the source tarball signature
- command: s3.put
params:
aws_secret: ${aws_secret}
local_file: src/mongodb-src-${src_suffix}.${ext|tar.gz}.sig
aws_key: ${aws_key}
bucket: build-push-testing
permissions: public-read
content_type: ${content_type|application/gzip}
remote_file: ${push_path}-STAGE/${push_name}/mongodb-src-${src_suffix}-${task_id}.${ext|tar.gz}.sig
build_variants: [rhel70, windows]
# Put the debug symbols signature
- command: s3.put
params:
@@ -8129,6 +8172,18 @@ tasks:
remote_file: ${push_path}-STAGE/${push_name}/mongodb-cryptd-${push_name}-${push_arch}-${suffix}-${task_id}.${ext|tgz}.sha1
build_variants: *mongocryptd_variants
# Put the source tarball sha1
- command: s3.put
params:
aws_secret: ${aws_secret}
local_file: src/mongodb-src-${src_suffix}.${ext|tar.gz}.sha1
aws_key: ${aws_key}
permissions: public-read
bucket: build-push-testing
content_type: text/plain
remote_file: ${push_path}-STAGE/${push_name}/mongodb-src-${src_suffix}-${task_id}.${ext|tar.gz}.sha1
build_variants: [rhel70, windows]
# Put the debug symbols sha1
- command: s3.put
params:
@@ -8187,6 +8242,18 @@ tasks:
remote_file: ${push_path}-STAGE/${push_name}/mongodb-cryptd-${push_name}-${push_arch}-${suffix}-${task_id}.${ext|tgz}.sha256
build_variants: *mongocryptd_variants
# Put the source tarball sha256
- command: s3.put
params:
aws_secret: ${aws_secret}
local_file: src/mongodb-src-${src_suffix}.${ext|tar.gz}.sha256
permissions: public-read
aws_key: ${aws_key}
bucket: build-push-testing
content_type: text/plain
remote_file: ${push_path}-STAGE/${push_name}/mongodb-src-${src_suffix}-${task_id}.${ext|tar.gz}.sha256
build_variants: [rhel70, windows]
# Put the debug symbols sha256
- command: s3.put
params:
@@ -8245,6 +8312,18 @@ tasks:
remote_file: ${push_path}-STAGE/${push_name}/mongodb-cryptd-${push_name}-${push_arch}-${suffix}-${task_id}.${ext|tgz}.md5
build_variants: *mongocryptd_variants
# Put the source tarball md5
- command: s3.put
params:
aws_secret: ${aws_secret}
local_file: src/mongodb-src-${src_suffix}.${ext|tar.gz}.md5
aws_key: ${aws_key}
bucket: build-push-testing
permissions: public-read
content_type: text/plain
remote_file: ${push_path}-STAGE/${push_name}/mongodb-src-${src_suffix}-${task_id}.${ext|tar.gz}.md5
build_variants: [rhel70, windows]
# Put the debug symbols md5
- command: s3.put
params:
@@ -8292,6 +8371,11 @@ tasks:
'destination': {'path': '${push_path}/mh-${push_name}-${push_arch}-${suffix}.${ext|tgz}', 'bucket': '${push_bucket}'},
'build_variants': *mh_variants}
#Source tarball
- {'source': {'path': '${push_path}-STAGE/${push_name}/mongodb-src-${src_suffix}-${task_id}.${ext|tar.gz}', 'bucket': 'build-push-testing'},
'destination': {'path': 'src/mongodb-src-${src_suffix}.${ext|tar.gz}', 'bucket': '${push_bucket}'},
'build_variants': ['rhel70', 'windows']}
#MSI (Windows only)
- {'source': {'path': '${push_path}-STAGE/${push_name}/mongodb-${push_name}-${push_arch}-${suffix}-${task_id}-signed.msi', 'bucket': 'build-push-testing'},
'destination': {'path': '${push_path}/mongodb-${push_name}-${push_arch}-${suffix}-signed.msi', 'bucket': '${push_bucket}'},
@@ -8310,6 +8394,11 @@ tasks:
'destination': {'path': '${push_path}/mongodb-cryptd-${push_name}-${push_arch}-${suffix}.${ext|tgz}.sig', 'bucket': '${push_bucket}'},
'build_variants': *mongocryptd_variants}
#Source tarball signature
- {'source': {'path': '${push_path}-STAGE/${push_name}/mongodb-src-${src_suffix}-${task_id}.${ext|tar.gz}.sig', 'bucket': 'build-push-testing'},
'destination': {'path': 'src/mongodb-src-${src_suffix}.${ext|tar.gz}.sig', 'bucket': '${push_bucket}'},
'build_variants': ['rhel70', 'windows']}
#SHA1 for binaries
- {'source': {'path': '${push_path}-STAGE/${push_name}/mongodb-${push_name}-${push_arch}-${suffix}-${task_id}.${ext|tgz}.sha1', 'bucket': 'build-push-testing'},
'destination': {'path': '${push_path}/mongodb-${push_name}-${push_arch}-${suffix}.${ext|tgz}.sha1', 'bucket': '${push_bucket}'}}
@@ -8323,6 +8412,11 @@ tasks:
'destination': {'path': '${push_path}/mongodb-cryptd-${push_name}-${push_arch}-${suffix}.${ext|tgz}.sha1', 'bucket': '${push_bucket}'},
'build_variants': *mongocryptd_variants}
#SHA1 for source tarball
- {'source': {'path': '${push_path}-STAGE/${push_name}/mongodb-src-${src_suffix}-${task_id}.${ext|tar.gz}.sha1', 'bucket': 'build-push-testing'},
'destination': {'path': 'src/mongodb-src-${src_suffix}.${ext|tar.gz}.sha1', 'bucket': '${push_bucket}'},
'build_variants': ['rhel70', 'windows']}
#SHA1 for MSI
- {'source': {'path': '${push_path}-STAGE/${push_name}/mongodb-${push_name}-${push_arch}-${suffix}-${task_id}-signed.msi.sha1', 'bucket': 'build-push-testing'},
'destination': {'path': '${push_path}/mongodb-${push_name}-${push_arch}-${suffix}-signed.msi.sha1', 'bucket': '${push_bucket}'},
@@ -8341,6 +8435,11 @@ tasks:
'destination': {'path': '${push_path}/mongodb-cryptd-${push_name}-${push_arch}-${suffix}.${ext|tgz}.sha256', 'bucket': '${push_bucket}'},
'build_variants': *mongocryptd_variants}
#SHA256 for source tarball
- {'source': {'path': '${push_path}-STAGE/${push_name}/mongodb-src-${src_suffix}-${task_id}.${ext|tar.gz}.sha256', 'bucket': 'build-push-testing'},
'destination': {'path': 'src/mongodb-src-${src_suffix}.${ext|tar.gz}.sha256', 'bucket': '${push_bucket}'},
'build_variants': ['rhel70', 'windows']}
#SHA256 for MSI files
- {'source': {'path': '${push_path}-STAGE/${push_name}/mongodb-${push_name}-${push_arch}-${suffix}-${task_id}-signed.msi.sha256', 'bucket': 'build-push-testing'},
'destination': {'path': '${push_path}/mongodb-${push_name}-${push_arch}-${suffix}-signed.msi.sha256', 'bucket': '${push_bucket}'},
@@ -8359,6 +8458,11 @@ tasks:
'destination': {'path': '${push_path}/mongodb-cryptd-${push_name}-${push_arch}-${suffix}.${ext|tgz}.md5', 'bucket': '${push_bucket}'},
'build_variants': *mongocryptd_variants}
#MD5 for source tarball
- {'source': {'path': '${push_path}-STAGE/${push_name}/mongodb-src-${src_suffix}-${task_id}.${ext|tar.gz}.md5', 'bucket': 'build-push-testing'},
'destination': {'path': 'src/mongodb-src-${src_suffix}.${ext|tar.gz}.md5', 'bucket': '${push_bucket}'},
'build_variants': ['rhel70', 'windows']}
#MD5 for MSIs
- {'source': {'path': '${push_path}-STAGE/${push_name}/mongodb-${push_name}-${push_arch}-${suffix}-${task_id}-signed.msi.md5', 'bucket': 'build-push-testing'},
'destination': {'path': '${push_path}/mongodb-${push_name}-${push_arch}-${suffix}-signed.msi.md5', 'bucket': '${push_bucket}'},
@@ -9978,16 +10082,33 @@ buildvariants:
test_flags: --excludeWithAnyTags=requires_increased_memlock_limits --enableEnterpriseTests=off
tasks:
- name: compile_all_run_unittests_TG
- name: aggregation
- name: .aggregation !.auth !.encrypt !.unwind
- name: .auth .gle
- name: auth_gen
- name: .causally_consistent !.sharding
- name: .change_streams !.secondary_reads
- name: .misc_js
- name: .concurrency !.ubsan !.no_txns !.debug_only !.kill_terminate
- name: disk_wiredtiger
- name: .jscore .common !.auth !.sharding
- name: initial_sync_fuzzer_gen
- name: .jscore .common !.auth
- name: .jstestfuzz .causal
- name: .jstestfuzz .interrupt
- name: .jstestfuzz .common
- name: .jstestfuzz .session
- name: .logical_session_cache .one_sec
- name: .query_fuzzer
- name: .read_write_concern !.linearize
- name: replica_sets
- name: replica_sets_kill_secondaries_jscore_passthrough
- name: .replica_sets .common !.auth
- name: retryable_writes_jscore_passthrough_gen
- name: .rollbackfuzzer
- name: session_jscore_passthrough
- name: .sharding .jscore !.wo_snapshot !.multi_stmt
- name: .sharding .txns
- name: .ssl
- name: .stitch
- name: push
- name: macos-debug
@@ -10005,12 +10126,16 @@ buildvariants:
- name: compile_build_tools_next_TG
- name: aggregation
- name: auth_gen
- name: causally_consistent_jscore_txns_passthrough
- name: disk_wiredtiger
- name: failpoints
- name: .jscore .common !.auth !.sharding
- name: jsCore_txns_large_txns_format
- name: mongosTest
- name: replica_sets
- name: replica_sets_large_txns_format_gen
- name: .ssl
- name: .stitch
- name: enterprise-macos
display_name: Enterprise macOS
@@ -10030,10 +10155,14 @@ buildvariants:
- name: compile_ninja_next_TG
- name: audit
- name: auth_audit_gen
- name: causally_consistent_jscore_txns_passthrough
- name: .encrypt !.replica_sets !.sharding !.aggregation !.jscore
- name: .jscore .common !.compat !.decimal !.sharding
- name: .jstestfuzz .common
- name: .logical_session_cache .one_sec
- name: mqlrun
- name: replica_sets_auth_gen
- name: replica_sets_jscore_passthrough
- name: sasl
- name: push

View File

@@ -83,7 +83,7 @@ modules:
prefix: ${workdir}/src
branch: master
- name: genny
owner: mongodb
owner: 10gen
repo: genny
prefix: ${workdir}/src
branch: master

View File

@@ -14,7 +14,7 @@ cat << 'EOF' > jsign_signing_commands.sh
function sign(){
if [ -e $1 ]
then
jsign -a mongo-authenticode-2021 --replace --tsaurl http://timestamp.digicert.com -d SHA-256 $1
jsign -a mongo-authenticode-2024 --replace --tsaurl http://timestamp.digicert.com -d SHA-256 $1
else
echo "$1 does not exist. Skipping signing"
fi

View File

@@ -167,6 +167,26 @@ void checkOverflow(std::unique_ptr<MessageCompressorBase> compressor) {
compressor->decompressData(tooSmallRange, DataRange(scratch.data(), scratch.size())));
}
void checkUndersize(const Message& compressedMsg,
std::unique_ptr<MessageCompressorBase> compressor) {
MessageCompressorRegistry registry;
const auto compressorName = compressor->getName();
std::vector<std::string> compressorList = {compressorName};
registry.setSupportedCompressors(std::move(compressorList));
registry.registerImplementation(std::move(compressor));
registry.finalizeSupportedCompressors().transitional_ignore();
MessageCompressorManager mgr(&registry);
BSONObjBuilder negotiatorOut;
auto negotiator = BSON("isMaster" << 1 << "compression" << BSON_ARRAY(compressorName));
mgr.serverNegotiate(negotiator, &negotiatorOut);
checkNegotiationResult(negotiatorOut.done(), {compressorName});
auto swm = mgr.decompressMessage(compressedMsg);
ASSERT_EQ(ErrorCodes::BadValue, swm.getStatus());
}
Message buildMessage() {
const auto data = std::string{"Hello, world!"};
const auto bufferSize = MsgData::MsgDataHeaderSize + data.size();
@@ -252,6 +272,52 @@ TEST(ZstdMessageCompressor, Overflow) {
checkOverflow(std::make_unique<ZstdMessageCompressor>());
}
TEST(ZlibMessageCompressor, Mismatch) {
checkOverflow(std::make_unique<ZlibMessageCompressor>());
}
TEST(SnappyMessageCompressor, Undersize) {
std::vector<std::uint8_t> payload = {
0x41, 0x0, 0x0, 0x0, 0xad, 0xde, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xdc,
0x7, 0x0, 0x0, 0xdd, 0x7, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x1, 0x27,
0x0, 0x0, 0x1, 0x1, 0x84, 0xfb, 0x1f, 0x0, 0x0, 0x5, 0x5f, 0x69, 0x64,
0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x48, 0x45, 0x41, 0x50, 0x4c, 0x45, 0x41,
0x4b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
auto buffer = SharedBuffer::allocate(payload.size());
std::copy(payload.begin(), payload.end(), buffer.get());
checkUndersize(Message(buffer), std::make_unique<SnappyMessageCompressor>());
}
TEST(ZlibMessageCompressor, Undersize) {
std::vector<std::uint8_t> payload = {
0x3c, 0x00, 0x00, 0x00, 0xad, 0xde, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x07, 0x00,
0x00, 0xdd, 0x07, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x02, 0x78, 0xda, 0x63, 0x60, 0x00,
0x82, 0xdf, 0xf2, 0x0c, 0x0c, 0xac, 0xf1, 0x99, 0x29, 0x0c, 0x0c, 0x02, 0x40, 0x9e, 0x87,
0xab, 0x63, 0x80, 0x8f, 0xab, 0xa3, 0x37, 0x03, 0x12, 0x00, 0x00, 0x6d, 0x26, 0x04, 0x97};
auto buffer = SharedBuffer::allocate(payload.size());
std::copy(payload.begin(), payload.end(), buffer.get());
checkUndersize(Message(buffer), std::make_unique<ZlibMessageCompressor>());
}
TEST(ZstdMessageCompressor, Undersize) {
std::vector<std::uint8_t> payload = {
0x44, 0x0, 0x0, 0x0, 0xad, 0xde, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xdc, 0x7,
0x0, 0x0, 0xdd, 0x7, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x3, 0x28, 0xb5, 0x2f,
0xfd, 0x20, 0x27, 0x15, 0x1, 0x0, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xfb, 0x1f,
0x0, 0x0, 0x5, 0x5f, 0x69, 0x64, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x48, 0x45,
0x41, 0x50, 0x4c, 0x45, 0x41, 0x4b, 0x0, 0x1, 0x0, 0x18, 0xc0, 0x9};
auto buffer = SharedBuffer::allocate(payload.size());
std::copy(payload.begin(), payload.end(), buffer.get());
checkUndersize(Message(buffer), std::make_unique<ZstdMessageCompressor>());
}
TEST(MessageCompressorManager, SERVER_28008) {
// Create a client and server that will negotiate the same compressors,

View File

@@ -74,7 +74,7 @@ StatusWith<std::size_t> ZlibMessageCompressor::decompressData(ConstDataRange inp
}
counterHitDecompress(input.length(), output.length());
return {output.length()};
return length;
}

View File

@@ -56,7 +56,6 @@
#include "mongo/util/fail_point.h"
#include "mongo/util/net/socket_exception.h"
#include "mongo/util/quick_exit.h"
#include "mongo/util/testing_proctor.h"
namespace mongo {
namespace {
@@ -493,14 +492,7 @@ void ServiceStateMachine::_processMessage(ThreadGuard guard) {
// Format our response, if we have one
Message& toSink = dbresponse.response;
if (!toSink.empty()) {
if (MONGO_unlikely(OpMsg::isFlagSet(_inMessage, OpMsg::kMoreToCome))) {
Status error = Status(ErrorCodes::InternalError,
"Attempted to respond to fire-and-forget request");
if (MONGO_unlikely(TestingProctor::instance().isEnabled())) {
invariant(error);
}
internalAssert(error);
}
invariant(!OpMsg::isFlagSet(_inMessage, OpMsg::kMoreToCome));
invariant(!OpMsg::isFlagSet(toSink, OpMsg::kChecksumPresent));
// Update the header for the response message.

View File

@@ -689,20 +689,6 @@ connection_runtime_config = [
interval in seconds at which to check for files that are
inactive and close them''', min=1, max=100000),
]),
Config('heuristic_controls', '', r'''
control the behavior of various optimizations. This is primarily used as a mechanism for
rolling out changes to internal heuristics while providing a mechanism for quickly
reverting to prior behavior in the field''',
type='category', subconfig=[
Config('obsolete_tw_btree_max', '100', r'''
maximum number of btrees that can be checked for obsolete time window cleanup in a
single checkpoint''',
min=0, max=500000),
Config('obsolete_tw_pages_dirty_max', '100', r'''
maximum number of pages that can be marked dirty because of obsolete time window
information per btree in a single checkpoint''',
min=0, max=100000),
]),
Config('io_capacity', '', r'''
control how many bytes per second are written and read. Exceeding
the capacity results in throttling.''',

View File

@@ -785,7 +785,6 @@ conn_dsrc_stats = [
CacheStat('cache_eviction_clean', 'unmodified pages evicted'),
CacheStat('cache_eviction_deepen', 'page split during eviction deepened the tree'),
CacheStat('cache_eviction_dirty', 'modified pages evicted'),
CacheStat('cache_eviction_dirty_obsolete_tw', 'pages dirtied due to obsolete time window'),
CacheStat('cache_eviction_hazard', 'hazard pointer blocked page eviction'),
CacheStat('cache_eviction_internal', 'internal pages evicted'),
CacheStat('cache_eviction_pages_seen', 'pages seen by eviction walk'),

View File

@@ -2,5 +2,5 @@
"vendor": "wiredtiger",
"github": "wiredtiger/wiredtiger.git",
"branch": "mongodb-4.4",
"commit": "002ce30f6845d6d070252a5b014168f7265a9448"
"commit": "d79240a8f58d3b3b4f92dd4151a54f9133f540cb"
}

View File

@@ -544,12 +544,6 @@ __wt_sync_file(WT_SESSION_IMPL *session, WT_CACHE_OP syncop)
btree->syncing = WT_BTREE_SYNC_WAIT;
__wt_gen_next_drain(session, WT_GEN_EVICT);
btree->syncing = WT_BTREE_SYNC_RUNNING;
/*
* Reset the number of obsolete time window pages to let the eviction threads continue
* marking the clean obsolete time window pages as dirty once the checkpoint is finished.
*/
btree->obsolete_tw_pages = 0;
is_hs = WT_IS_HS(btree->dhandle);
/* Add in history store reconciliation for standard files. */

View File

@@ -61,11 +61,6 @@ static const WT_CONFIG_CHECK confchk_wiredtiger_open_file_manager_subconfigs[] =
{"close_scan_interval", "int", NULL, "min=1,max=100000", NULL, 0},
{NULL, NULL, NULL, NULL, NULL, 0}};
static const WT_CONFIG_CHECK confchk_wiredtiger_open_heuristic_controls_subconfigs[] = {
{"obsolete_tw_btree_max", "int", NULL, "min=0,max=500000", NULL, 0},
{"obsolete_tw_pages_dirty_max", "int", NULL, "min=0,max=100000", NULL, 0},
{NULL, NULL, NULL, NULL, NULL, 0}};
static const WT_CONFIG_CHECK confchk_wiredtiger_open_history_store_subconfigs[] = {
{"file_max", "int", NULL, "min=0", NULL, 0}, {NULL, NULL, NULL, NULL, NULL, 0}};
@@ -122,8 +117,6 @@ static const WT_CONFIG_CHECK confchk_WT_CONNECTION_reconfigure[] = {
{"eviction_updates_target", "int", NULL, "min=0,max=10TB", NULL, 0},
{"eviction_updates_trigger", "int", NULL, "min=0,max=10TB", NULL, 0},
{"file_manager", "category", NULL, NULL, confchk_wiredtiger_open_file_manager_subconfigs, 3},
{"heuristic_controls", "category", NULL, NULL,
confchk_wiredtiger_open_heuristic_controls_subconfigs, 2},
{"history_store", "category", NULL, NULL, confchk_wiredtiger_open_history_store_subconfigs, 1},
{"io_capacity", "category", NULL, NULL, confchk_wiredtiger_open_io_capacity_subconfigs, 1},
{"log", "category", NULL, NULL, confchk_WT_CONNECTION_reconfigure_log_subconfigs, 4},
@@ -848,8 +841,6 @@ static const WT_CONFIG_CHECK confchk_wiredtiger_open[] = {
{"file_manager", "category", NULL, NULL, confchk_wiredtiger_open_file_manager_subconfigs, 3},
{"hash", "category", NULL, NULL, confchk_wiredtiger_open_hash_subconfigs, 2},
{"hazard_max", "int", NULL, "min=15", NULL, 0},
{"heuristic_controls", "category", NULL, NULL,
confchk_wiredtiger_open_heuristic_controls_subconfigs, 2},
{"history_store", "category", NULL, NULL, confchk_wiredtiger_open_history_store_subconfigs, 1},
{"in_memory", "boolean", NULL, NULL, NULL, 0},
{"io_capacity", "category", NULL, NULL, confchk_wiredtiger_open_io_capacity_subconfigs, 1},
@@ -931,8 +922,6 @@ static const WT_CONFIG_CHECK confchk_wiredtiger_open_all[] = {
{"file_manager", "category", NULL, NULL, confchk_wiredtiger_open_file_manager_subconfigs, 3},
{"hash", "category", NULL, NULL, confchk_wiredtiger_open_hash_subconfigs, 2},
{"hazard_max", "int", NULL, "min=15", NULL, 0},
{"heuristic_controls", "category", NULL, NULL,
confchk_wiredtiger_open_heuristic_controls_subconfigs, 2},
{"history_store", "category", NULL, NULL, confchk_wiredtiger_open_history_store_subconfigs, 1},
{"in_memory", "boolean", NULL, NULL, NULL, 0},
{"io_capacity", "category", NULL, NULL, confchk_wiredtiger_open_io_capacity_subconfigs, 1},
@@ -1012,8 +1001,6 @@ static const WT_CONFIG_CHECK confchk_wiredtiger_open_basecfg[] = {
{"file_manager", "category", NULL, NULL, confchk_wiredtiger_open_file_manager_subconfigs, 3},
{"hash", "category", NULL, NULL, confchk_wiredtiger_open_hash_subconfigs, 2},
{"hazard_max", "int", NULL, "min=15", NULL, 0},
{"heuristic_controls", "category", NULL, NULL,
confchk_wiredtiger_open_heuristic_controls_subconfigs, 2},
{"history_store", "category", NULL, NULL, confchk_wiredtiger_open_history_store_subconfigs, 1},
{"io_capacity", "category", NULL, NULL, confchk_wiredtiger_open_io_capacity_subconfigs, 1},
{"log", "category", NULL, NULL, confchk_wiredtiger_open_log_subconfigs, 10},
@@ -1090,8 +1077,6 @@ static const WT_CONFIG_CHECK confchk_wiredtiger_open_usercfg[] = {
{"file_manager", "category", NULL, NULL, confchk_wiredtiger_open_file_manager_subconfigs, 3},
{"hash", "category", NULL, NULL, confchk_wiredtiger_open_hash_subconfigs, 2},
{"hazard_max", "int", NULL, "min=15", NULL, 0},
{"heuristic_controls", "category", NULL, NULL,
confchk_wiredtiger_open_heuristic_controls_subconfigs, 2},
{"history_store", "category", NULL, NULL, confchk_wiredtiger_open_history_store_subconfigs, 1},
{"io_capacity", "category", NULL, NULL, confchk_wiredtiger_open_io_capacity_subconfigs, 1},
{"log", "category", NULL, NULL, confchk_wiredtiger_open_log_subconfigs, 10},
@@ -1169,9 +1154,7 @@ static const WT_CONFIG_ENTRY config_entries[] = {{"WT_CONNECTION.add_collator",
"eviction_dirty_trigger=20,eviction_target=80,eviction_trigger=95"
",eviction_updates_target=0,eviction_updates_trigger=0,"
"file_manager=(close_handle_minimum=250,close_idle_time=30,"
"close_scan_interval=10),"
"heuristic_controls=(obsolete_tw_btree_max=100,"
"obsolete_tw_pages_dirty_max=100),history_store=(file_max=0),"
"close_scan_interval=10),history_store=(file_max=0),"
"io_capacity=(total=0),log=(archive=true,os_cache_dirty_pct=0,"
"prealloc=true,zero_fill=false),lsm_manager=(merge=true,"
"worker_thread_max=4),operation_timeout_ms=0,"
@@ -1182,7 +1165,7 @@ static const WT_CONFIG_ENTRY config_entries[] = {{"WT_CONNECTION.add_collator",
"tiered_manager=(threads_max=8,threads_min=1,wait=0),"
"tiered_storage=(local_retention=300),timing_stress_for_test=,"
"verbose=[]",
confchk_WT_CONNECTION_reconfigure, 30},
confchk_WT_CONNECTION_reconfigure, 29},
{"WT_CONNECTION.rollback_to_stable", "", NULL, 0}, {"WT_CONNECTION.set_file_system", "", NULL, 0},
{"WT_CONNECTION.set_timestamp",
"commit_timestamp=,durable_timestamp=,force=false,"
@@ -1442,10 +1425,9 @@ static const WT_CONFIG_ENTRY config_entries[] = {{"WT_CONNECTION.add_collator",
"exclusive=false,extensions=,file_close_sync=true,file_extend=,"
"file_manager=(close_handle_minimum=250,close_idle_time=30,"
"close_scan_interval=10),hash=(buckets=512,dhandle_buckets=512),"
"hazard_max=1000,heuristic_controls=(obsolete_tw_btree_max=100,"
"obsolete_tw_pages_dirty_max=100),history_store=(file_max=0),"
"in_memory=false,io_capacity=(total=0),log=(archive=true,"
"compressor=,enabled=false,file_max=100MB,force_write_wait=0,"
"hazard_max=1000,history_store=(file_max=0),in_memory=false,"
"io_capacity=(total=0),log=(archive=true,compressor=,"
"enabled=false,file_max=100MB,force_write_wait=0,"
"os_cache_dirty_pct=0,path=\".\",prealloc=true,recover=on,"
"zero_fill=false),lsm_manager=(merge=true,worker_thread_max=4),"
"mmap=true,mmap_all=false,multiprocess=false,"
@@ -1461,7 +1443,7 @@ static const WT_CONFIG_ENTRY config_entries[] = {{"WT_CONNECTION.add_collator",
"timing_stress_for_test=,transaction_sync=(enabled=false,"
"method=fsync),use_environment=true,use_environment_priv=false,"
"verbose=[],verify_metadata=false,write_through=",
confchk_wiredtiger_open, 58},
confchk_wiredtiger_open, 57},
{"wiredtiger_open_all",
"buffer_alignment=-1,builtin_extension_config=,cache_cursors=true"
",cache_max_wait_ms=0,cache_overhead=8,cache_size=100MB,"
@@ -1479,10 +1461,9 @@ static const WT_CONFIG_ENTRY config_entries[] = {{"WT_CONNECTION.add_collator",
"exclusive=false,extensions=,file_close_sync=true,file_extend=,"
"file_manager=(close_handle_minimum=250,close_idle_time=30,"
"close_scan_interval=10),hash=(buckets=512,dhandle_buckets=512),"
"hazard_max=1000,heuristic_controls=(obsolete_tw_btree_max=100,"
"obsolete_tw_pages_dirty_max=100),history_store=(file_max=0),"
"in_memory=false,io_capacity=(total=0),log=(archive=true,"
"compressor=,enabled=false,file_max=100MB,force_write_wait=0,"
"hazard_max=1000,history_store=(file_max=0),in_memory=false,"
"io_capacity=(total=0),log=(archive=true,compressor=,"
"enabled=false,file_max=100MB,force_write_wait=0,"
"os_cache_dirty_pct=0,path=\".\",prealloc=true,recover=on,"
"zero_fill=false),lsm_manager=(merge=true,worker_thread_max=4),"
"mmap=true,mmap_all=false,multiprocess=false,"
@@ -1499,7 +1480,7 @@ static const WT_CONFIG_ENTRY config_entries[] = {{"WT_CONNECTION.add_collator",
"method=fsync),use_environment=true,use_environment_priv=false,"
"verbose=[],verify_metadata=false,version=(major=0,minor=0),"
"write_through=",
confchk_wiredtiger_open_all, 59},
confchk_wiredtiger_open_all, 58},
{"wiredtiger_open_basecfg",
"buffer_alignment=-1,builtin_extension_config=,cache_cursors=true"
",cache_max_wait_ms=0,cache_overhead=8,cache_size=100MB,"
@@ -1517,14 +1498,12 @@ static const WT_CONFIG_ENTRY config_entries[] = {{"WT_CONNECTION.add_collator",
"extensions=,file_close_sync=true,file_extend=,"
"file_manager=(close_handle_minimum=250,close_idle_time=30,"
"close_scan_interval=10),hash=(buckets=512,dhandle_buckets=512),"
"hazard_max=1000,heuristic_controls=(obsolete_tw_btree_max=100,"
"obsolete_tw_pages_dirty_max=100),history_store=(file_max=0),"
"io_capacity=(total=0),log=(archive=true,compressor=,"
"enabled=false,file_max=100MB,force_write_wait=0,"
"os_cache_dirty_pct=0,path=\".\",prealloc=true,recover=on,"
"zero_fill=false),lsm_manager=(merge=true,worker_thread_max=4),"
"mmap=true,mmap_all=false,multiprocess=false,"
"operation_timeout_ms=0,operation_tracking=(enabled=false,"
"hazard_max=1000,history_store=(file_max=0),io_capacity=(total=0)"
",log=(archive=true,compressor=,enabled=false,file_max=100MB,"
"force_write_wait=0,os_cache_dirty_pct=0,path=\".\",prealloc=true"
",recover=on,zero_fill=false),lsm_manager=(merge=true,"
"worker_thread_max=4),mmap=true,mmap_all=false,multiprocess=false"
",operation_timeout_ms=0,operation_tracking=(enabled=false,"
"path=\".\"),readonly=false,salvage=false,session_max=100,"
"session_scratch_max=2MB,session_table_cache=true,"
"shared_cache=(chunk=10MB,name=,quota=0,reserve=0,size=500MB),"
@@ -1536,7 +1515,7 @@ static const WT_CONFIG_ENTRY config_entries[] = {{"WT_CONNECTION.add_collator",
"timing_stress_for_test=,transaction_sync=(enabled=false,"
"method=fsync),verbose=[],verify_metadata=false,version=(major=0,"
"minor=0),write_through=",
confchk_wiredtiger_open_basecfg, 53},
confchk_wiredtiger_open_basecfg, 52},
{"wiredtiger_open_usercfg",
"buffer_alignment=-1,builtin_extension_config=,cache_cursors=true"
",cache_max_wait_ms=0,cache_overhead=8,cache_size=100MB,"
@@ -1554,14 +1533,12 @@ static const WT_CONFIG_ENTRY config_entries[] = {{"WT_CONNECTION.add_collator",
"extensions=,file_close_sync=true,file_extend=,"
"file_manager=(close_handle_minimum=250,close_idle_time=30,"
"close_scan_interval=10),hash=(buckets=512,dhandle_buckets=512),"
"hazard_max=1000,heuristic_controls=(obsolete_tw_btree_max=100,"
"obsolete_tw_pages_dirty_max=100),history_store=(file_max=0),"
"io_capacity=(total=0),log=(archive=true,compressor=,"
"enabled=false,file_max=100MB,force_write_wait=0,"
"os_cache_dirty_pct=0,path=\".\",prealloc=true,recover=on,"
"zero_fill=false),lsm_manager=(merge=true,worker_thread_max=4),"
"mmap=true,mmap_all=false,multiprocess=false,"
"operation_timeout_ms=0,operation_tracking=(enabled=false,"
"hazard_max=1000,history_store=(file_max=0),io_capacity=(total=0)"
",log=(archive=true,compressor=,enabled=false,file_max=100MB,"
"force_write_wait=0,os_cache_dirty_pct=0,path=\".\",prealloc=true"
",recover=on,zero_fill=false),lsm_manager=(merge=true,"
"worker_thread_max=4),mmap=true,mmap_all=false,multiprocess=false"
",operation_timeout_ms=0,operation_tracking=(enabled=false,"
"path=\".\"),readonly=false,salvage=false,session_max=100,"
"session_scratch_max=2MB,session_table_cache=true,"
"shared_cache=(chunk=10MB,name=,quota=0,reserve=0,size=500MB),"
@@ -1572,7 +1549,7 @@ static const WT_CONFIG_ENTRY config_entries[] = {{"WT_CONNECTION.add_collator",
"cache_directory=,local_retention=300,name=),"
"timing_stress_for_test=,transaction_sync=(enabled=false,"
"method=fsync),verbose=[],verify_metadata=false,write_through=",
confchk_wiredtiger_open_usercfg, 52},
confchk_wiredtiger_open_usercfg, 51},
{NULL, NULL, NULL, 0}};
int

View File

@@ -1982,26 +1982,6 @@ __wt_debug_mode_config(WT_SESSION_IMPL *session, const char *cfg[])
return (0);
}
/*
* __wt_heuristic_controls_config --
* Set heuristic_controls configuration.
*/
int
__wt_heuristic_controls_config(WT_SESSION_IMPL *session, const char *cfg[])
{
WT_CONFIG_ITEM cval;
WT_CONNECTION_IMPL *conn;
conn = S2C(session);
WT_RET(__wt_config_gets(session, cfg, "heuristic_controls.obsolete_tw_btree_max", &cval));
conn->heuristic_controls.obsolete_tw_btree_max = (uint32_t)cval.val;
WT_RET(__wt_config_gets(session, cfg, "heuristic_controls.obsolete_tw_pages_dirty_max", &cval));
conn->heuristic_controls.obsolete_tw_pages_dirty_max = (uint32_t)cval.val;
return (0);
}
/*
* __wt_verbose_config --
* Set verbose configuration.
@@ -2854,9 +2834,6 @@ wiredtiger_open(const char *home, WT_EVENT_HANDLER *event_handler, const char *c
*/
WT_ERR(__wt_debug_mode_config(session, cfg));
/* Parse the heuristic_controls configuration. */
WT_ERR(__wt_heuristic_controls_config(session, cfg));
/*
* Load the extensions after initialization completes; extensions expect everything else to be
* in place, and the extensions call back into the library.

View File

@@ -422,7 +422,6 @@ __wt_conn_reconfig(WT_SESSION_IMPL *session, const char **cfg)
WT_ERR(__wt_capacity_server_create(session, cfg));
WT_ERR(__wt_checkpoint_server_create(session, cfg));
WT_ERR(__wt_debug_mode_config(session, cfg));
WT_ERR(__wt_heuristic_controls_config(session, cfg));
WT_ERR(__wt_hs_config(session, cfg));
WT_ERR(__wt_logmgr_reconfig(session, cfg));
WT_ERR(__wt_lsm_manager_reconfig(session, cfg));

View File

@@ -557,119 +557,6 @@ __evict_child_check(WT_SESSION_IMPL *session, WT_REF *parent)
return (0);
}
/*
* __evict_review_obsolete_time_window --
* Check whether the ref has obsolete time window information and mark it for dirty eviction to
* remove those obsolete data. An exclusive lock on the page has already been obtained by the
* caller.
*/
static int
__evict_review_obsolete_time_window(WT_SESSION_IMPL *session, WT_REF *ref)
{
WT_ADDR_COPY addr;
WT_BTREE *btree;
WT_CONNECTION_IMPL *conn;
WT_MULTI *multi;
WT_PAGE_MODIFY *mod;
WT_TIME_AGGREGATE newest_ta;
wt_timestamp_t max_durable_ts;
uint32_t i;
char time_string[WT_TIME_STRING_SIZE];
btree = S2BT(session);
conn = S2C(session);
/* Too many pages have been cleaned for this btree. */
if (btree->obsolete_tw_pages >= conn->heuristic_controls.obsolete_tw_pages_dirty_max)
return (0);
/*
* Pages that the application threads are evicting should not be included. Reconciliation must
* be performed when converting a clean page to a dirty page, which can increase latency.
*/
if (!F_ISSET(session, WT_SESSION_EVICTION))
return (0);
/* Do not perform any obsolete time window cleanup during the startup or shutdown phase. */
if (F_ISSET(conn, WT_CONN_RECOVERING | WT_CONN_CLOSING_CHECKPOINT))
return (0);
/* If the file is being checkpointed, other threads can't evict dirty pages. */
if (__wt_btree_syncing_by_other_session(session))
return (0);
/*
* Rewriting internal pages doesn't clean the obsolete time window until the leaf pages are
* cleared from the obsolete time window.
*/
WT_ASSERT(session, ref->page != NULL);
if (WT_PAGE_IS_INTERNAL(ref->page))
return (0);
/* We are only interested in clean pages. */
if (__wt_page_is_modified(ref->page))
return (0);
/* Limit the number of btrees that can be cleaned up. */
if (btree->obsolete_tw_pages == 0 &&
conn->heuristic_controls.obsolete_tw_btree_count >=
conn->heuristic_controls.obsolete_tw_btree_max)
return (0);
/* Don't add more cache pressure. */
if (__wt_eviction_needed(session, false, false, NULL) || __wt_cache_stuck(session))
return (0);
/*
* Initialize the time aggregate via the merge initialization, so that stop visibility is copied
* across correctly. That is why we need the stop timestamp/transaction IDs to start as none,
* otherwise we'd never mark anything as obsolete.
*/
WT_TIME_AGGREGATE_INIT_MERGE(&newest_ta);
mod = ref->page->modify;
if (mod != NULL && mod->rec_result == WT_PM_REC_MULTIBLOCK) {
/* Calculate the max stop time point by traversing all multi addresses. */
for (multi = mod->mod_multi, i = 0; i < mod->mod_multi_entries; ++multi, ++i)
WT_TIME_AGGREGATE_MERGE(session, &newest_ta, &multi->addr.ta);
} else if (mod != NULL && mod->rec_result == WT_PM_REC_REPLACE)
WT_TIME_AGGREGATE_COPY(&newest_ta, &mod->mod_replace.ta);
else if (__wt_ref_addr_copy(session, ref, &addr))
WT_TIME_AGGREGATE_COPY(&newest_ta, &addr.ta);
/* Pages that are totally removed are eliminated during the checkpoint cleanup procedure. */
if (WT_TIME_AGGREGATE_HAS_STOP(&newest_ta))
return (0);
/* If there is no transaction or timestamp information available, there is nothing to do. */
max_durable_ts = WT_MAX(newest_ta.newest_start_durable_ts, newest_ta.newest_stop_durable_ts);
if (newest_ta.newest_txn == WT_TXN_NONE && max_durable_ts == WT_TS_NONE)
return (0);
/* Ensure the time window information has content that is globally visible. */
if (!__wt_txn_visible_all(session, newest_ta.newest_txn, max_durable_ts))
return (0);
/* Mark the page dirty to remove any obsolete information during reconciliation. */
__wt_verbose(session, WT_VERB_EVICT,
"%p in-memory page obsolete time window: time aggregate %s", (void *)ref,
__wt_time_aggregate_to_string(&newest_ta, time_string));
WT_RET(__wt_page_modify_init(session, ref->page));
__wt_page_modify_set(session, ref->page);
/*
* Save that another tree has been processed if that's the first time it gets cleaned and update
* the number of pages made dirty for that tree.
*/
if (btree->obsolete_tw_pages == 0)
conn->heuristic_controls.obsolete_tw_btree_count++;
btree->obsolete_tw_pages++;
WT_STAT_CONN_DATA_INCR(session, cache_eviction_dirty_obsolete_tw);
return (0);
}
/*
* __evict_review --
* Get exclusive access to the page and review the page and its subtree for conditions that
@@ -712,9 +599,6 @@ __evict_review(WT_SESSION_IMPL *session, WT_REF *ref, uint32_t evict_flags, bool
if (F_ISSET(session->dhandle, WT_DHANDLE_DEAD))
return (0);
/* Review the obsolete time window information before eviction. */
WT_RET(__evict_review_obsolete_time_window(session, ref));
/*
* Retrieve the modified state of the page. This must happen after the check for evictable
* internal pages otherwise there is a race where a page could be marked modified due to a child

View File

@@ -227,12 +227,6 @@ struct __wt_btree {
#define WT_BTREE_CLEAN_MINUTES 10
uint64_t clean_ckpt_timer;
/*
* Track the number of obsolete time window pages that are changed into dirty page
* reconciliation by the eviction.
*/
uint32_t obsolete_tw_pages;
/*
* We flush pages from the tree (in order to make checkpoint faster), without a high-level lock.
* To avoid multiple threads flushing at the same time, lock the tree.

View File

@@ -63,26 +63,6 @@ struct __wt_bucket_storage {
(s)->bucket_storage = __saved_bstorage; \
} while (0)
/*
* WT_HEURISTIC_CONTROLS --
* Heuristic controls configuration.
*/
struct __wt_heuristic_controls {
/*
* The controls below deal with the cleanup of obsolete time window information. This process
* can be configured on two levels:
* - The maximum number of btrees to process in a single checkpoint,
* - The maximum number of pages per btree to process in a single checkpoint.
*/
/* Number of btrees processed in the current checkpoint. */
uint32_t obsolete_tw_btree_count;
/* Maximum number of btrees that can be processed per checkpoint. */
uint32_t obsolete_tw_btree_max;
/* Maximum number of pages that can be processed per btree. */
uint32_t obsolete_tw_pages_dirty_max;
};
/*
* WT_KEYED_ENCRYPTOR --
* A list entry for an encryptor with a unique (name, keyid).
@@ -286,8 +266,6 @@ struct __wt_connection_impl {
/* Configuration */
const WT_CONFIG_ENTRY **config_entries;
WT_HEURISTIC_CONTROLS heuristic_controls; /* Heuristic controls configuration */
uint64_t operation_timeout_us; /* Maximum operation period before rollback */
const char *optrack_path; /* Directory for operation logs */

View File

@@ -771,8 +771,6 @@ extern int __wt_hazard_set_func(WT_SESSION_IMPL *session, WT_REF *ref, bool *bus
const char *func, int line
#endif
) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
extern int __wt_heuristic_controls_config(WT_SESSION_IMPL *session, const char *cfg[])
WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
extern int __wt_hex2byte(const u_char *from, u_char *to)
WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
extern int __wt_hex_to_raw(WT_SESSION_IMPL *session, const char *from, WT_ITEM *to)

View File

@@ -445,7 +445,6 @@ struct __wt_connection_stats {
int64_t cache_eviction_deepen;
int64_t cache_write_hs;
int64_t cache_pages_inuse;
int64_t cache_eviction_dirty_obsolete_tw;
int64_t cache_eviction_app;
int64_t cache_eviction_pages_in_parallel_with_checkpoint;
int64_t cache_eviction_pages_queued;
@@ -919,7 +918,6 @@ struct __wt_dsrc_stats {
int64_t cache_read_overflow;
int64_t cache_eviction_deepen;
int64_t cache_write_hs;
int64_t cache_eviction_dirty_obsolete_tw;
int64_t cache_read;
int64_t cache_read_deleted;
int64_t cache_read_deleted_prepared;

View File

@@ -162,7 +162,3 @@
if ((source)->prepare != 0) \
(dest)->prepare = 1; \
} while (0)
/* Check if the stop time aggregate is set. */
#define WT_TIME_AGGREGATE_HAS_STOP(ta) \
((ta)->newest_stop_txn != WT_TXN_MAX || (ta)->newest_stop_ts != WT_TS_MAX)

File diff suppressed because it is too large Load Diff

View File

@@ -199,8 +199,6 @@ struct __wt_fstream;
typedef struct __wt_fstream WT_FSTREAM;
struct __wt_hazard;
typedef struct __wt_hazard WT_HAZARD;
struct __wt_heuristic_controls;
typedef struct __wt_heuristic_controls WT_HEURISTIC_CONTROLS;
struct __wt_ikey;
typedef struct __wt_ikey WT_IKEY;
struct __wt_index;

View File

@@ -105,7 +105,6 @@ static const char *const __stats_dsrc_desc[] = {
"cache: overflow pages read into cache",
"cache: page split during eviction deepened the tree",
"cache: page written requiring history store records",
"cache: pages dirtied due to obsolete time window",
"cache: pages read into cache",
"cache: pages read into cache after truncate",
"cache: pages read into cache after truncate in prepare state",
@@ -374,7 +373,6 @@ __wt_stat_dsrc_clear_single(WT_DSRC_STATS *stats)
stats->cache_read_overflow = 0;
stats->cache_eviction_deepen = 0;
stats->cache_write_hs = 0;
stats->cache_eviction_dirty_obsolete_tw = 0;
stats->cache_read = 0;
stats->cache_read_deleted = 0;
stats->cache_read_deleted_prepared = 0;
@@ -630,7 +628,6 @@ __wt_stat_dsrc_aggregate_single(WT_DSRC_STATS *from, WT_DSRC_STATS *to)
to->cache_read_overflow += from->cache_read_overflow;
to->cache_eviction_deepen += from->cache_eviction_deepen;
to->cache_write_hs += from->cache_write_hs;
to->cache_eviction_dirty_obsolete_tw += from->cache_eviction_dirty_obsolete_tw;
to->cache_read += from->cache_read;
to->cache_read_deleted += from->cache_read_deleted;
to->cache_read_deleted_prepared += from->cache_read_deleted_prepared;
@@ -888,7 +885,6 @@ __wt_stat_dsrc_aggregate(WT_DSRC_STATS **from, WT_DSRC_STATS *to)
to->cache_read_overflow += WT_STAT_READ(from, cache_read_overflow);
to->cache_eviction_deepen += WT_STAT_READ(from, cache_eviction_deepen);
to->cache_write_hs += WT_STAT_READ(from, cache_write_hs);
to->cache_eviction_dirty_obsolete_tw += WT_STAT_READ(from, cache_eviction_dirty_obsolete_tw);
to->cache_read += WT_STAT_READ(from, cache_read);
to->cache_read_deleted += WT_STAT_READ(from, cache_read_deleted);
to->cache_read_deleted_prepared += WT_STAT_READ(from, cache_read_deleted_prepared);
@@ -1174,7 +1170,6 @@ static const char *const __stats_connection_desc[] = {
"cache: page split during eviction deepened the tree",
"cache: page written requiring history store records",
"cache: pages currently held in the cache",
"cache: pages dirtied due to obsolete time window",
"cache: pages evicted by application threads",
"cache: pages evicted in parallel with checkpoint",
"cache: pages queued for eviction",
@@ -1725,7 +1720,6 @@ __wt_stat_connection_clear_single(WT_CONNECTION_STATS *stats)
stats->cache_eviction_deepen = 0;
stats->cache_write_hs = 0;
/* not clearing cache_pages_inuse */
stats->cache_eviction_dirty_obsolete_tw = 0;
stats->cache_eviction_app = 0;
stats->cache_eviction_pages_in_parallel_with_checkpoint = 0;
stats->cache_eviction_pages_queued = 0;
@@ -2266,7 +2260,6 @@ __wt_stat_connection_aggregate(WT_CONNECTION_STATS **from, WT_CONNECTION_STATS *
to->cache_eviction_deepen += WT_STAT_READ(from, cache_eviction_deepen);
to->cache_write_hs += WT_STAT_READ(from, cache_write_hs);
to->cache_pages_inuse += WT_STAT_READ(from, cache_pages_inuse);
to->cache_eviction_dirty_obsolete_tw += WT_STAT_READ(from, cache_eviction_dirty_obsolete_tw);
to->cache_eviction_app += WT_STAT_READ(from, cache_eviction_app);
to->cache_eviction_pages_in_parallel_with_checkpoint +=
WT_STAT_READ(from, cache_eviction_pages_in_parallel_with_checkpoint);

View File

@@ -833,7 +833,6 @@ __txn_checkpoint(WT_SESSION_IMPL *session, const char *cfg[])
cache->evict_max_page_size = 0;
cache->evict_max_ms = 0;
cache->reentry_hs_eviction_ms = 0;
conn->heuristic_controls.obsolete_tw_btree_count = 0;
conn->rec_maximum_hs_wrapup_milliseconds = 0;
conn->rec_maximum_image_build_milliseconds = 0;
conn->rec_maximum_milliseconds = 0;

View File

@@ -173,7 +173,6 @@ functions:
# Autoconf/Libtool if $is_cmake_build is not declared.
if [ ${is_cmake_build|false} = true ]; then
if [ "$OS" = "Windows_NT" ]; then
export "PATH=/cygdrive/c/python/Python311:/cygdrive/c/python/Python311/Scripts:$PATH"
# Use the Windows powershell script to configure the CMake build.
# We execute it in a powershell environment as its easier to detect and source the Visual Studio
# toolchain in a native Windows environment. We can't easily execute the build in a cygwin environment.
@@ -240,9 +239,7 @@ functions:
${make_command|ninja} ${smp_command|} 2>&1
fi
elif [ "Windows_NT" == "$OS" ]; then
# Add paths to both global and user Python scripts
export "PATH=/cygdrive/c/python/Python311:/cygdrive/c/python/Python311/Scripts:$PATH"
export "PATH=/cygdrive/c/Users/$USER/AppData/Roaming/Python/Python311/Scripts:$PATH"
export "PATH=/cygdrive/c/Python311:/cygdrive/c/Python311/Scripts:$PATH"
python --version
python -m pip install scons==3.1.1
@@ -436,7 +433,7 @@ functions:
set -o verbose
if [ "Windows_NT" = "$OS" ]; then
export "PATH=/cygdrive/c/python/Python311:/cygdrive/c/python/Python311/Scripts:$PATH"
export "PATH=/cygdrive/c/Python311:/cygdrive/c/Python311/Scripts:$PATH"
export "PYTHONPATH=$(pwd)/../lang/python/wiredtiger):$(cygpath -w $(pwd)/../lang/python)"
fi
if [ ${is_cmake_build|false} = true ]; then
@@ -1989,10 +1986,7 @@ tasks:
set -o errexit
set -o verbose
# Add paths to both global and user Python scripts
export "PATH=/cygdrive/c/python/Python311:/cygdrive/c/python/Python311/Scripts:$PATH"
export "PATH=/cygdrive/c/Users/$USER/AppData/Roaming/Python/Python311/Scripts:$PATH"
export "PATH=/cygdrive/c/Python311:/cygdrive/c/Python311/Scripts:$PATH"
python --version
python -m pip install scons==3.1.1
scons-3.1.1.bat ${scons_smp_command|} "CFLAGS=/Gv /wd4090 /wd4996 /we4047 /we4024 /TC /we4100 /we4133" wiredtiger.dll libwiredtiger.lib
@@ -2010,10 +2004,7 @@ tasks:
set -o errexit
set -o verbose
# Add paths to both global and user Python scripts
export "PATH=/cygdrive/c/python/Python311:/cygdrive/c/python/Python311/Scripts:$PATH"
export "PATH=/cygdrive/c/Users/$USER/AppData/Roaming/Python/Python311/Scripts:$PATH"
export "PATH=/cygdrive/c/Python311:/cygdrive/c/Python311/Scripts:$PATH"
python --version
python -m pip install scons==3.1.1
# The check target is not run in parallel.
@@ -3615,7 +3606,7 @@ buildvariants:
run_on:
- windows-64-vs2017-test
expansions:
python_binary: '/cygdrive/c/python/Python311/python'
python_binary: 'python'
scons_smp_command: -j $(echo "$(getconf NPROCESSORS_ONLN 2>/dev/null || getconf _NPROCESSORS_ONLN 2>/dev/null || echo 1) * 2" | bc)
tasks:
- name: compile
@@ -3628,7 +3619,7 @@ buildvariants:
run_on:
- windows-64-vs2017-test
expansions:
python_binary: '/cygdrive/c/python/Python311/python'
python_binary: 'python'
is_cmake_build: true
test_env_vars: WT_BUILDDIR=$(git rev-parse --show-toplevel)/cmake_build
windows_configure_flags: -vcvars_bat "'C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC\Auxiliary\Build\vcvars64.bat'"

View File

@@ -1,47 +0,0 @@
#!/usr/bin/env python
#
# Public Domain 2014-present MongoDB, Inc.
# Public Domain 2008-2014 WiredTiger, Inc.
#
# This is free and unencumbered software released into the public domain.
#
# Anyone is free to copy, modify, publish, use, compile, sell, or
# distribute this software, either in source code form or as a compiled
# binary, for any purpose, commercial or non-commercial, and by any
# means.
#
# In jurisdictions that recognize copyright laws, the author or authors
# of this software dedicate any and all copyright interest in the
# software to the public domain. We make this dedication for the benefit
# of the public at large and to the detriment of our heirs and
# successors. We intend this dedication to be an overt act of
# relinquishment in perpetuity of all present and future rights to this
# software under copyright law.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.
import wttest
# eviction_util.py
# Shared base class used by eviction tests.
class eviction_util(wttest.WiredTigerTestCase):
def get_stat(self, stat, uri = ""):
stat_cursor = self.session.open_cursor(f'statistics:{uri}')
val = stat_cursor[stat][2]
stat_cursor.close()
return val
def populate(self, uri, start_key, num_keys, value):
c = self.session.open_cursor(uri, None)
for k in range(start_key, num_keys):
self.session.begin_transaction()
c[k] = value
self.session.commit_transaction("commit_timestamp=" + self.timestamp_str(k + 1))
c.close()

View File

@@ -1,98 +0,0 @@
#!/usr/bin/env python
#
# Public Domain 2014-present MongoDB, Inc.
# Public Domain 2008-2014 WiredTiger, Inc.
#
# This is free and unencumbered software released into the public domain.
#
# Anyone is free to copy, modify, publish, use, compile, sell, or
# distribute this software, either in source code form or as a compiled
# binary, for any purpose, commercial or non-commercial, and by any
# means.
#
# In jurisdictions that recognize copyright laws, the author or authors
# of this software dedicate any and all copyright interest in the
# software to the public domain. We make this dedication for the benefit
# of the public at large and to the detriment of our heirs and
# successors. We intend this dedication to be an overt act of
# relinquishment in perpetuity of all present and future rights to this
# software under copyright law.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.
from eviction_util import eviction_util
from wiredtiger import stat
from wtscenario import make_scenarios
# test_eviction02.py
# Verify evicting a clean page removes any obsolete time window information present on the page.
class test_eviction02(eviction_util):
conn_config_common = 'cache_size=10MB,statistics=(all),statistics_log=(json,wait=1,on_close=true)'
# These settings set a limit to the number of btrees/pages that can be cleaned up per btree per
# checkpoint.
conn_config_values = [
('no_btrees', dict(expected_cleanup=False, obsolete_tw_max=0, conn_config=f'{conn_config_common},heuristic_controls=[obsolete_tw_btree_max=0]')),
('no_pages', dict(expected_cleanup=False, obsolete_tw_max=0, conn_config=f'{conn_config_common},heuristic_controls=[obsolete_tw_pages_dirty_max=0]')),
('50_pages', dict(expected_cleanup=True, obsolete_tw_max=50, conn_config=f'{conn_config_common},heuristic_controls=[obsolete_tw_pages_dirty_max=50]')),
('100_pages', dict(expected_cleanup=True, obsolete_tw_max=100, conn_config=f'{conn_config_common},heuristic_controls=[obsolete_tw_pages_dirty_max=100]')),
('500_pages', dict(expected_cleanup=True, obsolete_tw_max=500, conn_config=f'{conn_config_common},heuristic_controls=[obsolete_tw_pages_dirty_max=500]')),
]
scenarios = make_scenarios(conn_config_values)
def test_evict(self):
create_params = 'key_format=i,value_format=S'
nrows = 10000
prev_obsolete_tw_value = 0
# Stats may have a stale value, allow some buffer.
threshold = self.obsolete_tw_max * 2
uri = 'table:eviction02'
value = 'k' * 1024
self.session.create(uri, create_params)
for i in range(10):
# Add some data.
start_key = nrows * i
num_keys = nrows * (i + 1)
self.populate(uri, start_key, num_keys, value)
# Make all the inserted data stable and checkpoint to make everything clean.
self.conn.set_timestamp('stable_timestamp=' + self.timestamp_str(num_keys))
self.session.checkpoint()
# Bump the oldest timestamp to make some of the previously inserted data globally
# visible. This makes any time window informaton associated with that data obsolete and
# eligible for cleanup.
self.conn.set_timestamp('oldest_timestamp=' + self.timestamp_str(num_keys // 2))
# Retrieve the number of pages we have cleaned up so far.
current_obsolete_tw_value = self.get_stat(stat.dsrc.cache_eviction_dirty_obsolete_tw, uri)
if self.expected_cleanup:
# The difference between two iterations should not exceed the maximum number of
# pages configured as each iteration contains one checkpoint that resets the limit.
# Note that we cannot assert after each iteration that we have cleaned pages as it
# depends on eviction that may not always work.
diff = current_obsolete_tw_value - prev_obsolete_tw_value
prev_obsolete_tw_value = current_obsolete_tw_value
assert diff <= threshold, f"Unexpected number of pages with obsolete tw cleaned: {diff} (max {threshold})"
else:
self.assertEqual(current_obsolete_tw_value, 0)
# Verify the btree and connection-level stat. If we expect some cleanup, by the end of the
# test, we must have done some work.
btree_stat = self.get_stat(stat.dsrc.cache_eviction_dirty_obsolete_tw, uri)
conn_stat = self.get_stat(stat.conn.cache_eviction_dirty_obsolete_tw)
if self.expected_cleanup:
self.assertGreater(btree_stat, 0)
self.assertGreater(conn_stat, 0)
else:
self.assertEqual(btree_stat, 0)
self.assertEqual(conn_stat, 0)