LW IT Solutions logo LW IT Solutions logo LW IT Solutions
« Przegląd bloga /Digital Analytics / Limit backfill w BigQuery Data Transfer i...
Ten artykuł w innych językach:

Limit backfill w BigQuery Data Transfer i zakres Google Signals: dwie zmiany w GA4 z czerwca 2026

Limit backfill w BigQuery Data Transfer i zakres Google Signals: dwie zmiany w GA4 z czerwca 2026
Spis treści
  1. Limit backfill w BigQuery Data Transfer i zakres Google Signals: dwie zmiany w GA4 z czerwca 2026
  2. 1. Limit backfill dotyczy konektorów raportowych
  3. 2. Kontrola dat kalendarzowych przed zaplanowaniem
  4. 3. Osobny punkt odtworzenia dla każdego przebiegu
  5. 4. Porównanie wszystkich dni i kontrola treści
  6. 5. Google Signals i Consent Mode sterują różnymi elementami
  7. 6. Osobny zapis ustawień i dowodów pomiarowych
  8. Pytania i odpowiedzi
  9. Źródła

Limit backfill w BigQuery Data Transfer i zakres Google Signals: dwie zmiany w GA4 z czerwca 2026

Dwie zmiany z czerwca 2026 r. wymagają osobnych kontroli. BigQuery Data Transfer Service ogranicza historyczne ponowne pobieranie danych kilku konektorów raportowych do 37 miesięcy. Google Signals steruje obecnie węższym powiązaniem danych Analytics, natomiast Ads Consent Mode reguluje odpowiednie zbieranie i użycie danych reklamowych. Zielony status dashboardu nie wystarcza do oceny tych zmian.

1. Limit backfill dotyczy konektorów raportowych

Backfill ponownie ładuje okres historyczny. Informacja o wydaniu BigQuery z 6 maja 2026 r. zapowiedziała, że od 1 czerwca 2026 r. konektory Data Transfer Service dla Google Ads, Search Ads 360 i Google Analytics 4 przestają uzupełniać backfill starszy niż 37 miesięcy. Dotyczy to tych konektorów, w tym konektora raportowych danych GA4. Nie jest to nowy limit retencji natywnego eksportu GA4 events_* ani automatyczne usuwanie istniejącej historii BigQuery.

Aktualny rejestr zmian rozróżnia wyniki: Google Ads i Search Ads 360 odrzucają dzienne uzupełnienia starsze niż 37 miesięcy błędem. Konektor Analytics ostrzega natomiast przed nadpisaniem historycznych partycji częściowymi lub pustymi wynikami.

Ograniczenie dziennych transferów nie dotyczy jednak wszystkich raportów Google Ads. Dane miesięczne, kwartalne i roczne pozostają dostępne do 11 lat; wskaźniki zasięgu i częstotliwości mają limit trzech lat.

Bezpośrednie zapytania do Google Ads API obejmujące okres sprzed ponad 37 miesięcy wymagają co najmniej miesięcznej segmentacji dat lub braku segmentacji oraz zakresu obejmującego pełne miesiące. Agregaty nie pozwalają odtworzyć szczegółów dziennych. Zakresy API odnoszą się do customer.time_zone konta emitującego reklamy. Poniższy przykład UTC przedstawia obliczenia kalendarzowe i wymaga dostosowania do konkretnego konektora oraz zasad harmonogramu; nie stanowi kompletnego walidatora dowolnych zapytań Google Ads API.

Przed backfillem: kontrola zakresu i zachowanie migawki. Po zakończeniu: porównanie liczb i treści. Nowy limit nie usuwa automatycznie istniejącej historii.
Przed backfillem: kontrola zakresu i zachowanie migawki. Po zakończeniu: porównanie liczb i treści. Nowy limit nie usuwa automatycznie istniejącej historii.

2. Kontrola dat kalendarzowych przed zaplanowaniem

Granica przesuwa się wraz z datą planowania. Zapisany zakres wymaga ponownej kontroli bezpośrednio przed wykonaniem, szczególnie po opóźnieniu lub ponowieniu zadania. Poniższa bramka w Pythonie używa UTC i ogranicza końce miesięcy do ostatniego prawidłowego dnia, podobnie jak BigQuery DATE_SUB z MONTH. Na przykład 31 marca 2026 r. minus 37 miesięcy daje 28 lutego 2023 r. GNU date może zamiast tego przenieść nieistniejącą datę lutową do marca; poprzednie obliczenie powłoki nie jest równoważne.

#!/usr/bin/env python3
import calendar
from datetime import date, datetime, timezone
import json
import re
import sys

def parse_day(value):
    if not re.fullmatch(r"[0-9]{4}-[0-9]{2}-[0-9]{2}", value):
        raise ValueError('Expected YYYY-MM-DD')
    return date.fromisoformat(value)

def months_before(day, months):
    month_index = day.year * 12 + day.month - 1 - months
    year, zero_month = divmod(month_index, 12)
    month = zero_month + 1
    return date(year, month, min(day.day, calendar.monthrange(year, month)[1]))

def validate(start_text, end_text, as_of):
    start, end = parse_day(start_text), parse_day(end_text)
    boundary = months_before(as_of, 37)
    if start > end:
        raise ValueError('Start is after end')
    if end > as_of:
        raise ValueError('End is in the future')
    if start < boundary:
        raise ValueError(f'Start precedes 37-month boundary {boundary}')
    return {'start': str(start), 'end': str(end),
            'as_of_utc': str(as_of), 'boundary': str(boundary)}

def main():
    if len(sys.argv) != 3:
        print('Usage: guard.py START END', file=sys.stderr)
        return 2
    try:
        result = validate(sys.argv[1], sys.argv[2], datetime.now(timezone.utc).date())
    except ValueError as exc:
        print(f'BLOCKED: {exc}', file=sys.stderr)
        return 1
    print(json.dumps(result))
    return 0

if __name__ == '__main__':
    sys.exit(main())

Przykład sprawdza pełne daty YYYY-MM-DD, początek niepóźniejszy od końca, brak przyszłego końca i granicę 37 miesięcy. Wypisuje dozwolony zakres, ale nie uruchamia transferu. Harmonogram musi przerwać działanie przy niezerowym kodzie i przekazać do właściwego polecenia dokładnie sprawdzone daty. Założenie UTC i reguły planowania konkretnego konta wymagają weryfikacji blisko granicy; dodatkowy bufor może wykluczyć przypadki graniczne. Bramka dotyczy wskazanych konektorów, a nie wszystkich rodzajów backfillu.

3. Osobny punkt odtworzenia dla każdego przebiegu

Przed ponownym ładowaniem nadpisującym dane potrzebne są jednoznacznie określone cel i kopia. Poniższe polecenie tworzy migawkę tabeli tylko do odczytu. CREATE TABLE AS SELECT tworzyłoby natomiast materializowaną kopię. PROJECT, DATASET, TARGET_TABLE i RUN_ID są symbolami zastępczymi; każdy przebieg wymaga nowego RUN_ID. Migawka i źródło muszą znajdować się w tej samej lokalizacji. Udane zakończenie zadania kopii jest warunkiem rozpoczęcia transferu.

-- Replace identifiers; use a fresh RUN_ID for every backfill.
-- Keep snapshot and source in the same location.
CREATE SNAPSHOT TABLE `PROJECT.audit.TARGET__RUN_ID`
CLONE `PROJECT.DATASET.TARGET_TABLE`;

Migawka obejmuje tabelę źródłową, a nie zakres wybrany przez WHERE. Dane w buforze strumieniowym i pozostałe ograniczenia migawek wymagają kontroli dla konkretnej tabeli. Inne zapisy do badanego zakresu muszą zostać wstrzymane lub uwzględnione podczas porównania. Istniejących nazw migawek nie należy nadpisywać. Odtworzenie do osobnej tabeli powinno zostać przećwiczone przed rzeczywistą awarią.

4. Porównanie wszystkich dni i kontrola treści

Po zakończeniu transferu zapytanie porównuje konkretną migawkę z obecną tabelą. Pełna lista dat obejmuje również puste dni. Brak tabeli powoduje błąd zapytania zamiast zera wierszy; brak grupy dla dnia w istniejącej tabeli rzeczywiście oznacza zero w tym zapytaniu. Przykład zakłada kolumnę PARTITION_DATE typu DATE. Partycjonowanie według czasu przyjęcia lub znacznika czasu wymaga jawnie dopasowanego wyrażenia daty.

-- Run only after the transfer has completed successfully.
-- @start_day and @end_day are DATE parameters from the validated range.
-- PARTITION_DATE is a DATE column in this example.
WITH days AS (
  SELECT day FROM UNNEST(GENERATE_DATE_ARRAY(@start_day, @end_day)) AS day
), before_counts AS (
  SELECT PARTITION_DATE AS day, COUNT(*) AS n
  FROM `PROJECT.audit.TARGET__RUN_ID`
  WHERE PARTITION_DATE BETWEEN @start_day AND @end_day
  GROUP BY day
), after_counts AS (
  SELECT PARTITION_DATE AS day, COUNT(*) AS n
  FROM `PROJECT.DATASET.TARGET_TABLE`
  WHERE PARTITION_DATE BETWEEN @start_day AND @end_day
  GROUP BY day
)
SELECT d.day,
       COALESCE(b.n, 0) AS rows_before,
       COALESCE(a.n, 0) AS rows_after,
       COALESCE(a.n, 0) - COALESCE(b.n, 0) AS delta,
       CASE
         WHEN COALESCE(b.n, 0) = 0 AND COALESCE(a.n, 0) = 0 THEN 'BOTH_EMPTY'
         WHEN COALESCE(a.n, 0) < COALESCE(b.n, 0) THEN 'FEWER_ROWS'
         WHEN COALESCE(a.n, 0) > COALESCE(b.n, 0) THEN 'MORE_ROWS'
         ELSE 'SAME_COUNT_REQUIRES_CONTENT_CHECK'
       END AS check_result
FROM days d
LEFT JOIN before_counts b USING (day)
LEFT JOIN after_counts a USING (day)
ORDER BY d.day;

Mniejsza liczba wierszy wymaga wyjaśnienia; większa liczba również jest zmianą, a nie automatycznym sukcesem. Równe liczby nie dowodzą identycznej treści: usunięte rekordy i nowe duplikaty mogą wzajemnie wyrównać wynik. Nadal potrzebne są kontrole kluczy biznesowych, istotnych metryk i wybranych pojedynczych rekordów. Migawka powinna pozostać do zakończenia walidacji i przewidzianego okna odtworzenia, zamiast znikać tylko dlatego, że liczba wierszy nie spadła.

5. Google Signals i Consent Mode sterują różnymi elementami

Zgodnie z komunikatem Google o kontrolach danych od 15 czerwca 2026 r. ustawienie Signals w administracji Analytics i odpowiednie API sterują wyłącznie powiązaniem danych Analytics z informacjami o zalogowanych użytkownikach na potrzeby raportowania zachowań. Powiązana zmiana przenosi kontrolę cookies i identyfikatorów Google Ads zbieranych przez tag lub SDK Analytics do Ads Consent Mode. Dotyczy to tego zakresu danych reklamowych, a nie wszystkich danych Analytics.

Typy zgód pozostają osobne: ad_storage dotyczy reklamowych cookies lub identyfikatorów urządzeń; analytics_storage dotyczy przechowywania analitycznego; ad_user_data dotyczy wysyłania danych użytkowników do reklamy internetowej; ad_personalization steruje reklamą spersonalizowaną. Ustawienie Signals nie zastępuje tych sygnałów. W zależności od wdrożenia podstawowego lub zaawansowanego odmowa przechowywania może nadal współistnieć z pingami pomiarowymi bez cookies. Wartość denied nie oznacza uniwersalnie braku wszystkich żądań sieciowych.

6. Osobny zapis ustawień i dowodów pomiarowych

Inwentaryzacja dla usługi może zapisywać czas pobrania, identyfikator usługi, stan Signals i źródło obserwacji. Udokumentowane żądanie Admin API tylko do odczytu wymaga ważnego access tokena, zakresu analytics.readonly i dostępu do usługi. PROPERTY_ID oraz ACCESS_TOKEN są symbolami zastępczymi; żądanie GET nie zmienia ustawienia.

GET /v1alpha/properties/PROPERTY_ID/googleSignalsSettings HTTP/1.1
Host: analyticsadmin.googleapis.com
Authorization: Bearer ACCESS_TOKEN
Accept: application/json

Odpowiedź ilustracyjna, a nie odczyt rzeczywistej usługi:

{
  "name": "properties/123456789/googleSignalsSettings",
  "state": "GOOGLE_SIGNALS_ENABLED",
  "consent": "GOOGLE_SIGNALS_CONSENT_CONSENTED"
}

Pole consent tego zasobu oznacza akceptację warunków Google Signals, a nie zgodę odwiedzającego witrynę. Brak stanu lub wartość unspecified nie potwierdzają włączenia Signals. Nieudane żądania muszą pozostać widoczne jako błędy; zaplanowana inwentaryzacja nie powinna jedynie dopisać błędu i zgłosić sukcesu. Porównanie wymaga dwóch udanych, datowanych obserwacji tej samej usługi. Ten szablon żądania nie implementuje automatycznej inwentaryzacji ani porównywania zmian.

Wskaźniki zgód wymagają osobnej definicji jednostki: zdarzenia, sesje i pojedyncze decyzje o zgodzie dają różne wyniki. W natywnym eksporcie GA4 pole privacy_info.ads_storage używa Yes, No i Unset, a nie granted/denied. Nieznane wartości należą do osobnej kategorii. Zmiana wskaźnika może wynikać ze struktury ruchu, zmian bannera lub wdrożeń; sam związek czasowy z czerwcem nie dowodzi wpływu Signals.

Pytania i odpowiedzi

Czy time travel może zastąpić kopię?

Time travel w BigQuery może umożliwić odtworzenie w skonfigurowanym oknie: domyślnie siedem dni, z możliwością ustawienia od dwóch do siedmiu dni. Migawka może zachować punkt odtworzenia dłużej. Koszty przechowywania migawki mogą wzrosnąć po zmianie lub usunięciu bloków źródłowych; mała zmiana logiczna może dotyczyć większych bloków fizycznych. Nie należy zakładać ani stale niskiego kosztu, ani nieograniczonego odtwarzania wstecz.

Czy niezmieniony czas modyfikacji partycji dowodzi braku zmian danych?

Nie. Metadane INFORMATION_SCHEMA.PARTITIONS zapewniają przydatny kontekst, ale część zmian, w tym usuwanie rekordów, może nie zostać odzwierciedlona w last_modified_time. Zliczenia, kontrole treści i rzeczywisty punkt odtworzenia służą różnym celom. Pojedyncze pole metadanych nie dowodzi kompletności.

Lukas Wójcik

Lukas Wójcik

Systems architect and technology enthusiast specializing in scalable tracking solutions, GMP Stack (GA4 & GTM), and robust backend architectures. Advocate for clean code and privacy-first design.

Kontakt

Masz pytanie lub pomysł na projekt internetowy? Napisz krótko, o co chodzi. Formularz korzysta z reCAPTCHA do ochrony przed spamem.

Napisanie komentarza

Odmienne wyniki z innych kont i pytania o konfigurację są tu mile widziane.

Adres e-mail nie jest publikowany. Pola obowiązkowe oznaczono gwiazdką.