이 게시물은 주로 JMP의 SQL 기능을 사용하는 것에 관한 것이지만 XML, Linux, MythTV도 다루고 있습니다.
SQL 쿼리 작성기 문서: https://www.jmp.com/support/help/14/query-builder.shtml#
MythTV https://www.mythtv.org/ PC의 튜너 카드를 사용하여 공중파 TV 방송을 녹화할 수 있는 오픈 소스 프로그램(TANSTAAFL)입니다. Linux 및 MySQL/MariaDB에 대해 배우고 TV 시청을 피할 수 있는 좋은 방법입니다. 이 구현은 녹화를 수행하는 백엔드(또는 여러 대)와 시청을 수행하는 프런트엔드(또는 여러 대)의 두 대의 컴퓨터를 사용합니다. SQL 데이터베이스는 기록할 내용과 기록된 내용을 추적합니다.
https://code.mythtv.org/trac/ticket/12974#no1 MythTV 프런트엔드에서 볼 수 없는 MythTV 백엔드 디스크에 정말 오래되고 정말 큰 파일이 많이 있는 이유를 설명합니다. 그것은 필드가 설정된 시간과 파일이 삭제되는 사이에 MythTV가 충돌하는 경우 파일이 삭제되지 않도록 하는 deletepending 데이터베이스 필드 주변에 MythTV 버그가 있다고 말합니다.
예를 들어 리눅스를 사용하여 ls 일부 파일을 나열하는 명령은 다음과 같습니다. 3GB 예제입니다(2019년 12월, 3T 디스크에 들어갈 수 있는 파일은 약 2주 정도입니다. 이 파일은 오래 전에 없어졌을 것입니다.)
-rw-r--r-- 1 신화TV 신화TV 3.1G 2018년 3월 21일 1051_20180321073000.ts
또는 데이터베이스 가져오기를 수행한 후
JMP data table imported from database showing old, large filesJMP data table imported from database showing old, large filesJMP data table imported from database showing old, large filesJMP data table imported from database showing old, large files오래된 대용량 파일을 보여주는 데이터베이스에서 가져온 JMP 데이터 테이블
데이터베이스 가져오기가 유용해 보입니다. 관련 값이 있는 열(또는 필드)을 서로 옆에 놓고 데이터베이스의 여러 테이블에서 정보를 결합합니다. 이를 수행하는 단계는 다음과 같습니다.
데이터베이스 자격 증명을 찾습니다.
MythTV 프런트엔드를 실행하는 Linux 시스템에는 ~/.mythtv/config.xml 파일이 있습니다.
<CONFIGURATION>
<LOCALHOSTNAME>my-unique-identifier-goes-here</LOCALHOSTNAME>
<DATABASE>
<PINGHOST>1</PINGHOST>
<HOST>closet.local</HOST>
<USERNAME>mythtv</USERNAME>
<PASSWORD>this is the pw</PASSWORD>
<DATABASENAME>mythconverg</DATABASENAME>
<PORT>3306</PORT>
</DATABASE>
<WAKEONLAN>
<ENABLED>0</ENABLED>
<SQLRECONNECTWAITTIME>0</SQLRECONNECTWAITTIME>
<SQLCONNECTRETRY>5</SQLCONNECTRETRY>
<COMMAND>echo 'WOLsqlServerCommand not set'</COMMAND>
</WAKEONLAN>
<UPNP>
<UDN>
<MEDIARENDERER>52d20477-fda1-4e42-9edd-5992bd0ca45f</MEDIARENDERER>
</UDN>
</UPNP>
</CONFIGURATION>
JMP 사본을 읽을 수 있는 위치에 파일을 복사하고 JMP 15에서 다음과 같이 엽니다.
// grab user name and password from the XML config file
dtConfig = Open( "F:\mythconfig.xml", invisible, XML Wizard( 0, guess( "huge" ) ) );
이렇게 숨겨진 테이블을 만들 것입니다
JMP data table loaded from XML file with one row and columns for UserName, Password, and DatabaseNameJMP data table loaded from XML file with one row and columns for UserName, Password, and DatabaseNameJMP data table loaded from XML file with one row and columns for UserName, Password, and DatabaseNameJMP data table loaded from XML file with one row and columns for UserName, Password, and DatabaseNameUserName, Password 및 DatabaseName에 대한 하나의 행과 열이 있는 XML 파일에서 로드된 JMP 데이터 테이블
Closet.local은 백엔드 호스트의 이름이고, mythtv는 mythconverg 데이터베이스에 액세스할 수 있는 SQL 사용자 이름이며, 3306은 기본 포트이므로 필요하지 않습니다.
Windows ODBC 데이터 원본 관리자를 사용하여 DSN을 만듭니다.
64비트 드라이버가 필요할 수 있으며 다운로드해야 할 수도 있습니다. https://dev.mysql.com/downloads/connector/odbc/ 아니면 어쩌면 https://downloads.mariadb.org/connector-odbc/+releases/ . 백엔드 서버에서 실제로 MariaDB를 실행하고 프런트엔드에서 MySQL 커넥터를 사용하고 있다고 확신합니다. https://www.google.com/search?q=mysql+vs+mariadb
The Windows ODBC Data Source Administrator sets up a DSNThe Windows ODBC Data Source Administrator sets up a DSNThe Windows ODBC Data Source Administrator sets up a DSNThe Windows ODBC Data Source Administrator sets up a DSNWindows ODBC 데이터 원본 관리자가 DSN을 설정합니다.
구성을 누르고 몇 개의 필드를 추가하십시오. 나중에 연결 문자열을 통해 이것들을 모두 재정의할 수 있다고 생각합니다. 내 VirtualBox와 네트워크 및 서버는 서버 이름에 대한 closet.local에 만족하지 않으므로 점으로 구분된 IP가 사용됩니다. 사용자와 암호를 입력하고 연결을 테스트하고 사용 가능한 데이터베이스 이름을 볼 수 있습니다. 아래의 JSL은 이를 재정의합니다.
The ODBC Connector dialog supplies some information that can be overridden laterThe ODBC Connector dialog supplies some information that can be overridden laterThe ODBC Connector dialog supplies some information that can be overridden laterThe ODBC Connector dialog supplies some information that can be overridden laterODBC 커넥터 대화 상자는 나중에 재정의할 수 있는 일부 정보를 제공합니다.
MythTV 데이터베이스에서 테이블 이름 찾기
의 예 덕분에 @briancorcoran JSL의 다음 비트로 길을 가리키기 위해.
https://community.jmp.com/t5/Discussions/How-do-I-get-the-list-of-the-databases-available-on-a-designated/mp/10589
// DSN=Mythtv comes from the windows ODBC Data Source Administrator applet
dt = Open Database(
"DSN=Mythtv;UID=" || dtConfig:UserName[1] || ";PWD=" || dtConfig:Password[1],
"SHOW tables from " || dtConfig:DatabaseName[1] || ";",
"tables in " || dtConfig:DatabaseName[1]
);
해당 JSL은 위의 XML 구성 파일에서 열린 dtConfig JMP 데이터 테이블을 사용하여 실제 암호 및 DSN(사용자 이름과 관련이 없는 mythtv라고도 함)을 재정의하기 위한 기타 정보를 가져옵니다. Brian의 예에서는 SHOW DATABASES를 사용했습니다. 이 JSL은 mythconverg에서 SHOW TABLES를 사용하여 mythconverg라는 이름의 mythtv 데이터베이스에서 80개 이상의 테이블을 가져옵니다.
(SQL은 여러 데이터베이스를 가질 수 있고 데이터베이스는 여러 테이블을 가질 수 있습니다. 데이터베이스는 서로 상호 작용하지 않지만 데이터베이스 내의 테이블에는 두 테이블을 결합할 수 있는 공통 키가 있는 경우가 많습니다. 애완동물용 데이터베이스, 요리법용 데이터베이스, MythTV용 데이터베이스입니다. MythTV 데이터베이스에는 녹화할 프로그램을 설명하는 테이블과 녹화된 프로그램을 설명하는 테이블 및 기타 많은 테이블이 있습니다...)
A JMP data table from Open Database(...) showing the 88 table names in the databaseA JMP data table from Open Database(...) showing the 88 table names in the databaseA JMP data table from Open Database(...) showing the 88 table names in the databaseA JMP data table from Open Database(...) showing the 88 table names in the database데이터베이스의 88개 테이블 이름을 보여주는 Open Database(...)의 JMP 데이터 테이블
데이터베이스의 형태를 파악하기 시작합니다.
이 작업을 잘못 수행하고 데이터베이스에 쓰면 데이터베이스가 손상됩니다. 당신은 읽을 수 있습니다 소스 코드 MythTV의 경우 테이블이 어떻게 작동하는지 설명하는 문서를 찾거나 흥미진진한 질문을 할 수 있습니다. 내일 녹화된 TV를 계속 볼 수 있습니까? 다음은 흥미로운 방법입니다.
위의 데이터 테이블에서 데이터베이스의 테이블 이름을 살펴보고 흥미로운 이름이 있는지 확인하십시오. 있지만 그들이 무엇을 나타내는지는 아직 명확하지 않습니다.
two of the high lighted table names, record and recorded, look promisingtwo of the high lighted table names, record and recorded, look promisingtwo of the high lighted table names, record and recorded, look promisingtwo of the high lighted table names, record and recorded, look promising밝은 테이블 이름 중 두 개(record 및 registered)가 유망해 보입니다.
다음은 테이블과 해당 열 및 약간의 데이터를 엿볼 수 있는 쉬운 방법입니다.
파일→데이터베이스→OpenTable
The OpenTable dialog opens one database table into a JMP data tableThe OpenTable dialog opens one database table into a JMP data tableThe OpenTable dialog opens one database table into a JMP data tableThe OpenTable dialog opens one database table into a JMP data tableOpenTable 대화 상자는 하나의 데이터베이스 테이블을 JMP 데이터 테이블로 엽니다.
이 테이블에는 50개의 열이 있지만 가장 먼저 나오는 것은 설명입니다.
The record table seems to describe what to recordThe record table seems to describe what to recordThe record table seems to describe what to recordThe record table seems to describe what to record레코드 테이블은 무엇을 기록할지 설명하는 것 같습니다.
무엇을 기록해야 하는지에 대한 설명입니다(또는 무엇을 기록하지 않아야 하는지… 제가 해당 규칙을 작성했습니다.) 이것은 제가 필요한 테이블이 아닙니다.
Recorded라는 이름의 테이블은 어떻습니까?
The recorded table seems to be a list of programs that were recordedThe recorded table seems to be a list of programs that were recordedThe recorded table seems to be a list of programs that were recordedThe recorded table seems to be a list of programs that were recorded녹화된 테이블은 녹화된 프로그램 목록인 것 같습니다.
녹화된 프로그램의 표처럼 보입니다. 이것이 출발점이 될 것입니다.
일부 테이블을 조인하여 필요한 모든 것을 한 곳에서 가져오기
파일→데이터베이스→쿼리 작성기, 기록된 테이블 선택...
Query Builder starts by choosing a single tableQuery Builder starts by choosing a single tableQuery Builder starts by choosing a single tableQuery Builder starts by choosing a single tableQuery Builder는 단일 테이블을 선택하여 시작합니다.
NEXT를 누르면 놀라운 결과를 얻을 수 있습니다. @Eric_Hill 중간 창:
The amazing Select Tables windows can view other tables and join them to the first tableThe amazing Select Tables windows can view other tables and join them to the first tableThe amazing Select Tables windows can view other tables and join them to the first tableThe amazing Select Tables windows can view other tables and join them to the first table놀라운 테이블 선택 창은 다른 테이블을 보고 첫 번째 테이블에 조인할 수 있습니다.
이 창은 테이블을 탐색하기 위한 것입니다. 쿼리 작성을 아직 클릭하지 마십시오. 그러면 열을 선택할 창으로 이동합니다. 그 전에 이 창을 사용하여 다른 테이블에 조인하십시오.
(나중에 이 창으로 다시 돌아올 수 있지만 나중에 처음 방문할 때 필요한 모든 것을 찾을 수 있어야 합니다...아마도요.)
Clicking a table shows a snapshotClicking a table shows a snapshotClicking a table shows a snapshotClicking a table shows a snapshot테이블을 클릭하면 스냅샷이 표시됩니다.
다음은 내가 사용하여 마무리한 것입니다(거의 한 가지 변경 사항은 아래 참조).
Three more tables joined with the firstThree more tables joined with the firstThree more tables joined with the firstThree more tables joined with the first첫 번째와 조인된 세 개의 추가 테이블
나는 데이터베이스가 기억하는 파일 크기를 얻기 위해 registeredfile(위에서 선택)을 사용했습니다. 내 생각에 이 데이터베이스는 녹음 및 녹음 파일에 기본 이름이 나타나기 때문에 정규화되지 않은 것 같습니다... https://en.wikipedia.org/wiki/Database_normalization
(하단의 버튼은 내가 이 그림을 얻기 위해 Build Query에서 go-back-to-select-more-tables 빨간색 삼각형 버튼을 사용했기 때문에 다릅니다... 확인을 누르면 Build Query 창으로 돌아갑니다.)
여기에는 많은 기능이 있습니다. 파란색 원 버튼으로 조인을 제어할 수 있고 열에 있는 모든 테이블의 스냅샷을 볼 수 있으며 조인 결과를 미리 볼 수 있습니다. 그리고 모든 테이블이 나열됩니다! 여기에서 퍼즐이 풀리는 곳입니다. 어떤 테이블이 필요하고 테이블이 어떻게 연결되어 있습니까? 테이블 스냅샷 탭을 선택하고 왼쪽 열에서 테이블을 선택한 다음 아래쪽 화살표를 사용하여 각 테이블을 봅니다. 많은 MythTV 테이블이 비어 있으므로 무시할 수 있습니다.
유지할 열 선택
쿼리 작성 버튼을 클릭할 시간입니다. 이 창에서는 원하는 열을 선택하고 쿼리를 시도할 수 있습니다.
Build Query window chooses columns to keep in the JMP data tableBuild Query window chooses columns to keep in the JMP data tableBuild Query window chooses columns to keep in the JMP data tableBuild Query window chooses columns to keep in the JMP data tableBuild Query 창에서 JMP 데이터 테이블에 보관할 열 선택
이중 X 버튼은 모든 열 선택을 삭제합니다. 선택한 열만 삭제하려면 단일 X를 클릭하고 싶을 것입니다. 열을 설명하는 행을 위아래로 이동하여 열을 정렬하고 열을 선택하여 데이터를 미리 정렬합니다.
쿼리 실행 선택, 테이블 연구, 다시 생각…
위의 대화 상자에서 테이블 옆에 있는 빨간색 삼각형을 클릭하면 다른 테이블 추가 대화 상자(놀라운 것)로 돌아갑니다. 무슨 일이 일어나고 있는지 실제로 이해하려면 다른 테이블이 필요했습니다.
Added another table, recgroupAdded another table, recgroupAdded another table, recgroupAdded another table, recgroup다른 테이블, recgroup을 추가했습니다.
recgroups 테이블에는 삭제된 그룹 표시기가 있습니다. 다음은 약간의 결과입니다(상단의 원래 테이블과 유사). 이러한 모든 기본 이름은 삭제된 그룹이 아니라 기본 그룹에 있습니다.
The filesize column suggests there is a lot of space I might recoverThe filesize column suggests there is a lot of space I might recoverThe filesize column suggests there is a lot of space I might recoverThe filesize column suggests there is a lot of space I might recover파일 크기 열은 복구할 수 있는 많은 공간이 있음을 나타냅니다.
너무 많은 공간을 잃었습니다!
다음은 표에 있는 소스 스크립트의 JSL/SQL입니다. 추가 편집을 위해 빌더 대화 상자에서 열려면 <<실행을 <<수정으로 변경하십시오!
New SQL Query(
Connection( "ODBC:DSN=mythtv;SERVER=192.168.0.39;UID=mythtv;DATABASE=mythconverg;PORT=3306;PWD=%_PWD_%;"
),
QueryName( "recorded" ),
Select(
Column( "callsign", "t3" ),
Column( "channum", "t3" ),
Column( "starttime", "t1", Numeric Format( "m/d/y h:m:s", "0", "NO", "" ) ),
Column( "endtime", "t1", Numeric Format( "m/d/y h:m:s", "0", "NO", "" ) ),
Column( "title", "t1" ),
Column( "description", "t1" ),
Column( "autoexpire", "t1" ),
Column( "preserve", "t1" ),
Column( "deletepending", "t1" ),
Column( "recgroup", "t4" ),
Column( "basename", "t2" ),
Column( "filesize", "t2" ),
Column( "width", "t2" ),
Column( "height", "t2" ),
Column( "fps", "t2" ),
Column( "videoprop", "t5" ),
Column( "subtitletypes", "t5" )
),
From(
Table( "recorded", Alias( "t1" ) ),
Table( "recgroups", Alias( "t4" ),
Join( Type( Left Outer ),
EQ( Column( "recgroupid", "t1" ), Column( "recgroupid", "t4" ) )
)
),
Table( "recordedprogram", Alias( "t5" ),
Join(
Type( Left Outer ),
EQ( Column( "chanid", "t1" ), Column( "chanid", "t5" ) ) &
EQ(
Column("starttime","t1",Numeric Format( "m/d/y h:m:s", "0", "NO", "" ) ),
Column("starttime","t5",Numeric Format( "m/d/y h:m:s", "0", "NO", "" ) )
)
)
),
Table( "recordedfile", Alias( "t2" ),
Join( Type( Left Outer ),
EQ( Column( "recordedid", "t1" ), Column( "recordedid", "t2" ) )
)
),
Table( "channel", Alias( "t3" ),
Join( Type( Left Outer ),
EQ( Column( "chanid", "t1" ), Column( "chanid", "t3" ) )
)
)
),
Order By( Column( "starttime", "t1", Numeric Format( "m/d/y h:m:s", "0", "NO", "" ),
Order( "Ascending" ) )
)
) << Run;
작은 테스트를 수행해야 합니다. 하나의 고정된 파일에 대해 데이터베이스를 터치하여 자동 만료를 다시 설정하고 삭제 보류를 해제합니다. 그리고 백엔드를 중지했다가 다시 시작할 수도 있습니다. 그런 다음 다음 몇 시간 또는 며칠 내에 파일이 삭제되는지 확인하십시오. MythTV의 동작 중 일부인 적시 삭제도 혼란스럽습니다.
시간 음. 천천히 가는 것이 좋습니다. 총 파일 크기 데이터베이스에서 ~이다 두 배로 크다 디스크.다음 항목을 삭제하겠습니다: 1171_20180321043700.ts
먼저 검색어를 만들어 찾습니다. 필터를 사용하여. JMP가 GUI에서 나를 위해 대부분의 작업을 수행할 수 있고 일부 도움 없이는 SQL을 작성하는 것이 완전히 편하지 않기 때문에 이 경로를 선택합니다. JMP가 어려운 부분을 처리한 후에 SQL을 수정하겠습니다.
Add a filter to select a single basename (file)Add a filter to select a single basename (file)Add a filter to select a single basename (file)Add a filter to select a single basename (file)단일 기본 이름(파일)을 선택하는 필터 추가
멋진! 필터가 WHERE 절을 SQL에 추가했고 정확히 하나의 행이 발견되었습니다. SQL을 복사해야 할 때라고 생각합니다. 쿼리 빌더 대화; mythconverg를 추가해야 합니다. 각 테이블 이름 앞에 :
// grab user name and password from the XML config file
dtConfig = Open( "F:\mythconfig.xml", invisible, XML Wizard( 0, guess( "huge" ) ) );
//https://community.jmp.com/t5/Discussions/How-do-I-get-the-list-of-the-databases-available-on-a-designated/m-p/10589
// dtConfig:UserName,Password,DatabaseName
//
// DSN=Mythtv comes from the windows ODBC Data Source Administrator applet
dbc=CreateDatabaseConnection("DSN=Mythtv;UID=" || dtConfig:UserName[1] || ";PWD=" || dtConfig:Password[1]);
rc=executesql(dbc,"\[
SELECT t3.callsign, t3.channum, t1.starttime, t1.endtime,
t1.title, t1.description, t1.autoexpire, t1.preserve,
t1.deletepending, t4.recgroup, t2.basename, t2.filesize,
t2.width, t2.height, t2.fps, t5.videoprop,
t5.subtitletypes
FROM mythconverg.recorded t1
LEFT OUTER JOIN mythconverg.recgroups t4
ON ( t1.recgroupid = t4.recgroupid )
LEFT OUTER JOIN mythconverg.recordedprogram t5
ON ( ( t1.chanid = t5.chanid ) AND ( t1.starttime = t5.starttime ) )
LEFT OUTER JOIN mythconverg.recordedfile t2
ON ( t1.recordedid = t2.recordedid )
LEFT OUTER JOIN mythconverg.channel t3
ON ( t1.chanid = t3.chanid )
WHERE ( ( ( t2.basename="1171_20180321043700.ts" ) ) )
ORDER BY t1.starttime ASC;
]\","one row");
Close Database Connection(dbc);
close(dtConfig,nosave);
show(nrows(rc)==1); // better only be one row
경고, 위험한 코드가 뒤따릅니다. 업데이트 및 설정으로 데이터베이스를 지울 수 있습니다.
SELECT를 교체하고... 에서 ~와 함께 UPDATE 및 SET 절 추가 및 ORDER BY 제거:
// grab user name and password from the XML config file
dtConfig = Open( "F:\mythconfig.xml", invisible, XML Wizard( 0, guess( "huge" ) ) );
dbc=CreateDatabaseConnection("DSN=Mythtv;UID=" || dtConfig:UserName[1] || ";PWD=" || dtConfig:Password[1]);
rc=executesql(dbc,"\[
UPDATE mythconverg.recorded t1
LEFT OUTER JOIN mythconverg.recgroups t4
ON ( t1.recgroupid = t4.recgroupid )
LEFT OUTER JOIN mythconverg.recordedprogram t5
ON ( ( t1.chanid = t5.chanid ) AND ( t1.starttime = t5.starttime ) )
LEFT OUTER JOIN mythconverg.recordedfile t2
ON ( t1.recordedid = t2.recordedid )
LEFT OUTER JOIN mythconverg.channel t3
ON ( t1.chanid = t3.chanid )
SET t1.autoexpire=1, t1.deletepending=0
WHERE ( ( ( t2.basename="1171_20180321043700.ts" ) ) );
]\","update");
Close Database Connection(dbc);
close(dtConfig,nosave);
테이블을 다시 가져오면 업데이트가 표시됩니다.
The UPDATE and SET workedThe UPDATE and SET workedThe UPDATE and SET workedThe UPDATE and SET workedUPDATE 및 SET가 작동했습니다.
업데이트 상태를 확인하는 방법을 모르겠습니다. rc는 누락된 값이고 테이블이 생성되지 않았습니다. 이는 의미가 있습니다. 그러나 그것은 효과가 있었다…
몇 분이 지난 후에도 파일은 여전히 존재합니다. 백엔드를 다시 시작하겠습니다. 다시 시작했습니다. 이제 파일이 프런트엔드에 표시됩니다.
Part of the frontend GUI shows the ancient file is visible againPart of the frontend GUI shows the ancient file is visible againPart of the frontend GUI shows the ancient file is visible againPart of the frontend GUI shows the ancient file is visible again프런트엔드 GUI의 일부는 고대 파일이 다시 표시됨을 보여줍니다.
나는 앉아서 며칠 안에 디스크에서 사라지는 지 볼 것입니다. 그런 다음 이와 같은 나머지 작업을 수행하고 데이터베이스가 3T 디스크에 6T가 있다고 생각하는 이유를 확인합니다...
몇 시간 후에: ls: '1171_20180321043700.ts'에 액세스할 수 없습니다. 해당 파일 또는 디렉터리가 없습니다.
위에서 언급한 방식(정규화된 주석)과 같이 파일 이름은 둘 이상의 테이블에 나타납니다. 6T를 보다 현실적인 3T로 정리하려는 나의 계획은 기록된 테이블에 더 이상 디스크에 없는 파일을 참조하는 항목이 있다고 가정합니다. 두 테이블(또는 그 이상?)에서 레코드를 삭제하려고 시도하는 대신 더미 파일이 없는 경우 더미 파일을 만들고 기존 코드가 일반적인 방식으로 처리하도록 할 것입니다. 좋은 첫 번째 단계는 기록 및 기록 파일 데이터베이스 테이블을 모두 JMP 데이터 테이블로 열고 디스크에서 누락된 파일이 있고 테이블 간에 일치하지 않는 파일이 있는 위치를 식별하는 것일 수 있습니다.
파일→데이터베이스→OpenTable이 수행합니다. 기본 이름 및 기록 ID를 제외한 모든 열을 삭제하고 기록 ID별로 정렬하고 데이터 테이블을 비교합니다. 세 가지 차이점을 클릭하십시오. 쉬운.
궁금함: 1171_20180317233200.ts는 녹음되었지만 녹음된 파일은 아닙니다.
0바이트 파일로 존재 -rw-rw-r-- 1 mythtv mythtv 0 2018년 4월 4일 1171_20180317233200.ts
그리고 기록된 파일에는 이름이 모두 비어 있고 기록된 파일에는 일치하는 기록 ID가 없는 두 개의 항목이 있습니다. 아마도 그것들을 정리하고 싶지 않을 것이고, 다른 테이블이 그것들을 참조할 수 있는 것을 말하지 않을 것입니다.
위에서 삭제된 파일, 1171_20180321043700.ts , 어느 테이블에도 나타나지 않습니다. 예이!
빈 기록이 없기 때문에 기록을 진실로 사용하겠습니다. 진행 상황을 확인하는 데 도움이 되도록 fileexists() 함수와 함께 열 수식을 사용하겠습니다.
Graph; points at top represent real files on disk, points at bottom are files that are not on diskGraph; points at top represent real files on disk, points at bottom are files that are not on diskGraph; points at top represent real files on disk, points at bottom are files that are not on diskGraph; points at top represent real files on disk, points at bottom are files that are not on disk그래프; 상단의 점은 디스크의 실제 파일을 나타내고 하단의 점은 디스크에 없는 파일을 나타냅니다.
많은 디스크 공간을 다시 확보할 가능성이 있지만 삭제하려는 클러스터에 길이가 0 또는 거의 0에 가까운 파일이 많이 있을 수 있습니다. 휴식 시간, 오후 9시에 시작하면 안 됩니다.
"얼마나?" 질문, fileexists() 대신 filesize()를 사용하십시오. 많은 파일이 존재하지만 0바이트이므로 복구 가능한 공간은 약 0.3T(10% !) 정도에 불과합니다.
1단계: MythTV가 나중에 정리할 수 있도록 존재하지 않는 파일에 대한 더미 파일을 추가합니다. MythTV가 파일을 찾을 수 없을 때 레코드가 데이터베이스에 남아 있는 이유는 MythTV가 파일이 사용할 수 없는 디스크에 있을 수 있고 데이터베이스 항목이 제거되면 고아가 될 것이라고 가정하기 때문입니다.
// actualsize is this formula:
// File Size( "f:/closet/" || :basename )
For Each Row(
If( :basename != "" & Is Missing( actualsize ),
If( !File Exists( "f:/closet/" || :basename ),
Show( :basename );
Save Text File( "f:/closet/" || :basename, "hi there" );// use “touch” on Linux
, // else
Throw( "oops" )
)
)
);
Write( "\!ndone" );
2단계: 데이터베이스의 새 복사본을 데이터 테이블로 가져옵니다. 좋아 보인다. 업데이트할 레코드만 선택할 수 있는지 확인하기 위해 SQL을 재작업할 시간입니다.
// grab user name and password from the XML config file
dtConfig = Open( "F:\mythconfig.xml", invisible, XML Wizard( 0, guess( "huge" ) ) );
dbc=CreateDatabaseConnection("DSN=Mythtv;UID=" || dtConfig:UserName[1] || ";PWD=" || dtConfig:Password[1]);
rc=executesql(dbc,"\[
SELECT t3.callsign, t3.channum, t1.starttime, t1.endtime,
t1.title, t1.description, t1.autoexpire, t1.preserve,
t1.deletepending, t4.recgroup, t2.basename, t2.filesize,
t2.width, t2.height, t2.fps, t5.videoprop,
t5.subtitletypes
FROM mythconverg.recorded t1
LEFT OUTER JOIN mythconverg.recgroups t4
ON ( t1.recgroupid = t4.recgroupid )
LEFT OUTER JOIN mythconverg.recordedprogram t5
ON ( ( t1.chanid = t5.chanid ) AND ( t1.starttime = t5.starttime ) )
LEFT OUTER JOIN mythconverg.recordedfile t2
ON ( t1.recordedid = t2.recordedid )
LEFT OUTER JOIN mythconverg.channel t3
ON ( t1.chanid = t3.chanid )
WHERE ( ( ( t1.deletepending=1 ) ) )
ORDER BY t1.starttime ASC;
]\","one row");
Close Database Connection(dbc);
close(dtConfig,nosave);
show(nrows(rc)==1);
그것은 삭제 보류 상태로 걸려있는 꽤 오래된 레코드의 약 절반을 선택합니다. 대담해질 시간…
3단계: 하세요.
경고, 위험한 코드가 뒤따릅니다. 업데이트 및 설정으로 데이터베이스를 지울 수 있습니다.
// grab user name and password from the XML config file
dtConfig = Open( "F:\mythconfig.xml", invisible, XML Wizard( 0, guess( "huge" ) ) );
dbc=CreateDatabaseConnection("DSN=Mythtv;UID=" || dtConfig:UserName[1] || ";PWD=" || dtConfig:Password[1]);
rc=executesql(dbc,"\[
UPDATE mythconverg.recorded t1
LEFT OUTER JOIN mythconverg.recgroups t4
ON ( t1.recgroupid = t4.recgroupid )
LEFT OUTER JOIN mythconverg.recordedprogram t5
ON ( ( t1.chanid = t5.chanid ) AND ( t1.starttime = t5.starttime ) )
LEFT OUTER JOIN mythconverg.recordedfile t2
ON ( t1.recordedid = t2.recordedid )
LEFT OUTER JOIN mythconverg.channel t3
ON ( t1.chanid = t3.chanid )
SET t1.autoexpire=1, t1.deletepending=0
WHERE ( ( ( t1.deletepending=1 ) ) );
]\","update");
Close Database Connection(dbc);
close(dtConfig,nosave);
삭제 보류는 더 이상 보류되지 않으며 자동 만료가 다시 설정됩니다. 기다릴 시간입니다.
다음날 아침: 효과가 있는 것 같습니다. 더 나은 메모를 했어야했습니다. 다음은 아침 뉴스 쇼가 녹화되기 전(월요일 오전 6시 50분)에 여전히 남아 있는 가장 오래된 파일입니다.
-rw-r--r-- 1 mythtv mythtv 1.9G 2018년 3월 22일 1111_20180322080000.ts
-rw-r--r-- 1 mythtv mythtv 3.2G 2018년 3월 22일 1051_20180322080000.ts
-rw-rw-rw- 1 mythtv mythtv 1.1M 2018년 3월 22일 1111_20180322043700.ts.png
-rw-r--r-- 1 mythtv mythtv 11G 2018년 3월 22일 1171_20180322060700.ts
-rw-r--r-- 1 mythtv mythtv 5.6G 2018년 3월 22일 1111_20180322063000.ts
-rw-rw-rw- 1 mythtv mythtv 1.4M 2018년 3월 22일 1051_20180322033500.ts.png
-rw-r--r-- 1 mythtv mythtv 3.2G 2018년 3월 22일 1051_20180322070000.ts
-rw-r--r-- 1 mythtv mythtv 5.7G 2018년 3월 22일 1051_20180322060700.ts
-rw-r--r-- 1 mythtv mythtv 3.2G 2018년 3월 22일 1051_20180322053700.ts
-rw-r--r-- 1 mythtv mythtv 1.6G 2018년 3월 22일 1111_20180322053700.ts
-rw-r--r-- 1 mythtv mythtv 6.4G 2018년 3월 22일 1051_20180322043700.ts
-rw-r--r-- 1 mythtv mythtv 5.4G 2018년 3월 22일 1171_20180322043700.ts
-rw-rw-rw- 1 mythtv mythtv 1.4M 2018년 3월 22일 1171_20180322030000.ts.png
-rw-rw-rw- 1 mythtv mythtv 3.4M 2018년 3월 22일 1051_20180322030100.ts.png
-rw-r--r-- 1 mythtv mythtv 2.1G 2018년 3월 22일 1111_20180322043700.ts
-rw-rw-rw- 1 mythtv mythtv 511K 2018년 3월 22일 1111_20180322030000.ts.png
-rw-r--r-- 1 mythtv mythtv 6.6G 2018년 3월 22일 1051_20180322033500.ts
-rw-r--r-- 1 mythtv mythtv 3.8G 2018년 3월 22일 1111_20180322033500.ts
-rw-r--r-- 1 mythtv mythtv 3.3G 2018년 3월 21일 1171_20180322030000.ts
-rw-r--r-- 1 신화tv 신화tv 3.7G 2018년 3월 21일 1051_20180322030100.ts
-rw-r--r-- 1 mythtv mythtv 2.4G 2018년 3월 21일 1111_20180322030000.ts
-rw-r--r-- 1 신화tv 신화tv 3.3G 2018년 3월 21일 1051_20180321233000.ts
-rw-rw-rw- 1 mythtv mythtv 725K 2018년 3월 21일 1111_20180321200000.ts.png
-rw-rw-rw- 1 mythtv mythtv 2.6M 2018년 3월 21일 1051_20180321200000.ts.png
-rw-r--r-- 1 mythtv mythtv 2.9G 2018년 3월 21일 1051_20180321200000.ts
-rw-r--r-- 1 mythtv mythtv 1.8G 2018년 3월 21일 1111_20180321200000.ts
-rw-rw-rw- 1 mythtv mythtv 897K 2018년 3월 21일 1111_20180321163000.ts.png
-rw-r--r-- 1 mythtv mythtv 3.2G 2018년 3월 21일 1051_20180321163000.ts
-rw-r--r-- 1 mythtv mythtv 2.0G 2018년 3월 21일 1111_20180321163000.ts
-rw-r--r-- 1 mythtv mythtv 2.0G 2018년 3월 21일 1111_20180321160000.ts
-rw-r--r-- 1 mythtv mythtv 102M 2018년 3월 21일 1171_20180321160000.ts
-rw-r--r-- 1 mythtv mythtv 26G 2018년 3월 21일 1051_20180321110000.ts
-rw-r--r-- 1 mythtv mythtv 8.1G 2018년 3월 21일 1111_20180321110000.ts
-rw-r--r-- 1 mythtv mythtv 3.3G 2018년 3월 21일 1171_20180321100000.ts
-rw-r--r-- 1 mythtv mythtv 6.2G 2018년 3월 21일 1051_20180321100000.ts
-rw-r--r-- 1 mythtv mythtv 3.9G 2018년 3월 21일 1111_20180321100000.ts
-rw-rw-rw- 1 mythtv mythtv 743K 2018년 3월 20일 1281_20180321010000.ts.png
-rw-rw-rw- 1 mythtv mythtv 867K 2018년 3월 20일 1281_20180321002000.ts.png
drwxr-xr-x 12 루트 루트 4.0K 2018년 3월 20일 ..
drwx------ 2 루트 루트 16K 2018년 2월 28일 분실+발견
Programs recorded Friday will be recorded again today (Monday)Programs recorded Friday will be recorded again today (Monday)Programs recorded Friday will be recorded again today (Monday)Programs recorded Friday will be recorded again today (Monday)금요일 녹화된 프로그램은 오늘(월요일) 다시 녹화됩니다.
이 세 프로그램은 지난 금요일에 약 40GB를 사용했습니다. 9시 30분에 기록된 테이블의 마지막 13.4G가 삭제되었습니다. 다른 15G가 어디에서 왔는지 잘 모르겠습니다. 삭제 대기열에 이미 일부 파일이 있을 수 있습니다. 아마도 이것들은 가장 오래된 순서대로 추가되었을 것입니다. 다른 것 이후에... 저는 주간 TV를 녹화하지 않으려고 노력하므로 더 많은 파일이 삭제되는 것을 보기 전에 오늘 밤이 될 것입니다. (예, 일어나고 있습니다!) png(거대한) 썸네일이 스스로를 너무 빨리 처리하기를 바랍니다.
JMP 및 SQL에 대해 배운 것: 조인이 필요하지 않은 경우 SQL 테이블을 JMP 데이터 테이블에 로드하는 정말 간단한 방법이 있습니다(파일→데이터베이스→테이블 열기). (File→Database→Query Builder.) 둘 다 재사용할 수 있는 JSL 스크립트를 테이블에 생성합니다. 그리고 데이터베이스를 업데이트해야 하는 경우 ExecueSQL() 함수를 사용해야 하지만 쿼리 빌더를 사용하여 거의 필요한 SQL을 만든 다음 업데이트/설정을 수행하도록 변경할 수 있습니다.
저는 과거에 JMP 외부에서 일부 SQL 작업을 수행했습니다. JSL을 사용하여 데이터베이스를 더 잘 이해하는 데 도움이 되는 비 SQL 작업(더미 파일 생성, 디스크 사용 그래프 만들기)을 수행하는 것이 정말 좋습니다.
https://code.mythtv.org/cgit/mythtv/tree/mythtv/programs/mythbackend/autoexpire.cpp 오래된 파일 정리와 관련된 MythTV 소스 코드의 시작점
https://en.wikipedia.org/wiki/Cord-cutting
모든 것이 정상으로 돌아온 것 같습니다. 이 최종 그래프는 서로 다른 스테이션이 사용 가능한 대역폭을 어떻게 최적화했는지 보여줍니다. 대역폭은 하나 이상의 채널로 나눌 수 있습니다. 더 많은 채널 감소는 고품질 이미지를 만드는 데 더 적은 데이터를 의미합니다. 지역 방송국 중 하나는 또한 1080 30FPS가 아닌 720 60FPS를 사용하기로 선택했습니다. 이는 아마도 사과 대 사과 비교가 아님을 의미합니다. 강조 표시된 각 채널에는 대역폭을 공유하는 동일한 스테이션의 다른 채널이 하나 이상 있을 수 있습니다. 하단의 회색 스테이션은 동시에 여러 개의 오래된 영화 또는 쇼핑 채널을 실행 중일 수 있습니다. 그들은 전설에서 제거되었습니다.
Lines with bigger slope have more bandwidth allocated to the pictureLines with bigger slope have more bandwidth allocated to the pictureLines with bigger slope have more bandwidth allocated to the pictureLines with bigger slope have more bandwidth allocated to the picture기울기가 더 큰 라인은 그림에 더 많은 대역폭이 할당됩니다.